laravel 미들웨어 의 생 성 방향 에 대하 여 말씀 드 리 겠 습 니 다.
그러면 소프트웨어 실행 과정 을 간소화 하 겠 습 니 다.현재 핵심 클래스 인 kernel 이 있 습 니 다.다음은 laravel 코드 입 니 다.
#
$request = Illuminate\Http\Request::capture()
#
$response = $kernel->handle($request);
코드 의 역할 은 Request 를 캡 처 하여 Response 를 되 돌려 주 는 것 입 니 다.이 안 은 논 리 를 구체 적 으로 수행 하 는 코드 세그먼트 에 추가 로 배포 하고 결 과 를 되 돌려 주 는 것 이다.그렇다면 이$kernel->handle()방법 을 실행 하기 전이 나 그 후에 논 리 를 추가 하려 면 어떻게 쓰 는 것 일 까?대략 다음 과 같다.
$request = Illuminate\Http\Request::capture()
function midware(){
before()#
#####
$response = $kernel->handle($request);
#####
after()#
}
분명히 이렇게 쓰 는 것 은 문제 가 없 지만 확장 성 이 없다.무엇 을 실행 하려 면 이 방법 을 바 꿔 야 한다.이런 것 은 구조의 핵심 내용 으로 포장 할 수 없다.어떻게 개선 할 까요?실행 할 미들웨어 류 를 middleware 라 고 정의 합 니 다.클래스 는 두 가지 방법 을 실현 합 니 다.before()와 after()다음 코드 는 다음 과 같 습 니 다.
# :
middleware = '';
$request = Illuminate\Http\Request::capture()
function midware(){
middleware.before()
#####
$response = $kernel->handle($request);
#####
middleware.after()
}
문 제 를 해결 하 였 습 니까?변경 하지 않 아 도 되 는 문 제 를 해결 하 였 습 니 다.그러나 우리 가 여러 개의 미들웨어 가 필요 하 다 면 어떻게 해 야 합 니까?가장 쉽게 생각 나 는 것 은 미들웨어 배열 middleware 를 정의 하 는 것 입 니 다.arr,모든 middleware 류 는 before 와 after 방법 을 포함 하고 코드 는 다음 과 같 습 니 다.
middleware_arr
middleware_arr=array();
$request = Illuminate\Http\Request::capture()
function midware(){
foreach(middleware_arr as middleware){
middleware.before()
}
#####
$response = $kernel->handle($request);
#####
foreach(middleware_arr as middleware){
middleware.after()
}
}
좀 촌 스 럽 긴 하지만 확실히 문 제 를 해결 했다.그러나 이것 은 또 하나의 문제 가 존재 한다.바로 우리 가 중간 부품 에 어떻게 파 라 메 터 를 전달 하 는 지 하 는 문제 이다.그러면 다음 과 같이 할 수 있 습 니까?
$request = Illuminate\Http\Request::capture()
function midware(){
foreach(middleware_arr as middleware){
middleware.before($request)
}
#####
$response = $kernel->handle($request);
#####
foreach(middleware_arr as middleware){
middleware.after($response)
}
}
문 제 를 해결 한 것 처럼 보이 지만 자세히 분석 해 보면 이 안에 중간 부품 을 줄 때마다 최초의$request 가 있 습 니 다.이것 은 분명 안 됩 니 다.다음 과 같이 수정 되 었 습 니 다.
$request = Illuminate\Http\Request::capture()
function midware(){
foreach(middleware_arr as middleware){
$request = middleware.before($request)
}
#####
$response = $kernel->handle($request);
#####
foreach(middleware_arr as middleware){
$response = middleware.after($response)
}
}
또 하나의 문 제 는 두 개의 미들웨어 A 와 B 가 있다 고 가정 하면 집행 순 서 는 어떻게 되 어야 하 는가 하 는 것 이다.
$request = Illuminate\Http\Request::capture()
$request = A.before($request);
$request = B.before($request);
$response = $kernel->handle($request);
$response = A.after();
$response = B.after();
이렇게 하 는 것 이 합 리 적 입 니까?구분 하기 가 쉽 지 않 습 니 다.요청 과 응답 로 그 를 기록 하 는 미들웨어 가 있다 고 가정 합 니 다.이 럴 때 는 어떤 위치 에 두 든 최초의 요청 과 최종 로 그 를 완벽 하 게 기록 할 수 없습니다.유사 한 상황 에서 두 가지 종 류 를 써 야 합 니까?하나의 기록 요청 은 미들웨어 배열 의 첫 번 째,하나의 처리 응답 을 배열 의 마지막 에 두 어야 합 니까?뒤에 있 는 foreach 를 실행 하기 전에 middlewarearr 배열 을 반전 시 키 면 요구 에 부합 합 니 다.
$request = Illuminate\Http\Request::capture()
$request = A.before($request);
$request = B.before($request);
$response = $kernel->handle($request);
$response = B.after();
$response = A.after();
그러나 나 도 이 촌 스 럽 고 융통성 이 없 는 방안 이 더 좋 은 해결 방법 이 있 는 지 의심 하기 시작 했다.이 집행 순 서 를 관찰 할 때 소포 양식(양파 식)이라는 것 을 발견 했다.그 다음 문 제 는 더욱 유연 하고 아름 다운 해결 방안 을 찾 을 수 있 습 니까?위의 이런 구 조 를 보면 약간 익숙 한 것 같 습 니 다.그 는 A 의 함수 가 B 를 감 싸 는 함수 같 습 니 다.B 의 함 수 는 최초의 실행 코드 를 포함 합 니 다.함수 내부 호출 함수 가 쉽 지만,여기 있 는 모든 미들웨어 사 이 는 상대방 이 존재 하 는 지 모 르 기 때문에 다른 미들웨어 가 실행 할 함 수 를 이전 단계 로 전달 해 야 합 니 다.여 기 는 폐쇄 함수 와 phop 함수 array 를 사용 합 니 다.reduce(),array_reduce 함수 정의:mixed arrayreduce ( array $input , callable $function [, mixed $initial = NULL ] )
<?php
function rsum ( $v , $w ){
$v += $w ;
return $v ;
}
function rmul ( $v , $w ){
$v *= $w ;
return $v ;
}
$a = array( 1 , 2 , 3 , 4 , 5 );
$x = array();
$b = array_reduce ( $a , "rsum" );
$c = array_reduce ( $a , "rmul" , 10 );
?>
출력:이것 은$b 의 값 은 15,$c 입 니 다. 의 값 은 1200(=10*1*2*3*4*5)
array_reduce()는 리 셋 함수 function 을 input 배열 의 모든 단원 에 교체 적 으로 작용 하여 배열 을 단일 한 값 으로 간소화 합 니 다.우 리 는 여러 함 수 를 최종 호출 함수 로 감 쌌 다.
# middleware, log , , , 。
$middleware_arr = ['log'];
# , , , 。
$default = function() use($request){
return $kernel->handle($request);
}
$callback = array_reduce($middleware_arr,function($stack,$pipe) {
return function() use($stack,$pipe){
return $pipe::handle($stack);
};
},$default);
# callback :
function() use($default,$log){
return $log::handle($default);
};
# handle , , ,
class log implements Milldeware {
public static function handle(Closure $func){
$func();
}
}
# :
class log implements Milldeware {
public static function handle(Closure $func){
# before()
$func();
# after()
}
}
이렇게 콜백 함 수 를 실행 할 때 실행 순 서 는 다음 과 같 습 니 다.먼저 log::haddle()방법 을 실행 합 니 다.
log::before()방법 을 실 행 했 습 니 다.
default 방법 을 실행 하고$kernel->handle($request)을 실행 합 니 다.
실행 로그::after()방법
그리고 여러 개의 상황 을 모 의 하면 다음 과 같다.
$middleware_arr = ['csrf','log'];
# , , , 。
$default = function() use($request){
return $kernel->handle($request);
}
$callback = array_reduce($middleware_arr,function($stack,$pipe) {
return function() use($stack,$pipe){
return $pipe::handle($stack);
};
},$default);
# callback :
$log::handle(function() use($default,$csrf){
return $csrf::handle($default);
});
실행 순 서 는 다음 과 같 습 니 다.1.먼저 log::haddle(csrf:handle 폐쇄 함수 포함)방법 을 실행 합 니 다.
2.log::before()방법 을 실 행 했 습 니 다.
3.패 키 지 를 실행 하면$csrf:handle($default)이 실 행 됩 니 다.
4.csrf::before()방법 을 실 행 했 습 니 다.
5.default 방법 을 실행 하고$kernel->handle($request)을 실행 합 니 다.
6.csrf::after()방법 을 실 행 했 습 니 다.
7.log 실행::after()방법
여기 서 또 하나의 문 제 는 미들웨어 가 발생 한 결과 가 전달 되 지 않 았 다 는 것 이다.공유 자원 을 수정 하 는 방식 으로 똑 같은 목적 을 달성 할 수 있 고 다음 미들웨어 로 전달 해 야 하 는 것 이 아니다.
여기까지 이 서 류 는 끝 났 습 니 다.사실 그 중 많은 관절 은 제 가 이 글 을 쓸 때 생각 한 것 입 니 다.특히 패 킷 함수 에 대한 운용 과 이해 가 더욱 깊 어 졌 다.패 킷 함 수 는 자원 이용 을 지연 시 킬 수 있다.예 를 들 어 현재 실행 하기에 적합 하지 않 은 문 구 는 뒤로 전달 하고 패 킷 을 이용 하여 포장 하여 전달 할 수 있다.이것 은 전통 함수 가 할 수 없 는 것 이다.
이상 은 laravel 미들웨어 의 생 성 사고 에 대한 상세 한 내용 입 니 다.laravel 미들웨어 의 생 성 사고 에 관 한 자 료 는 우리 의 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Laravel - 변환된 유효성 검사 규칙으로 API 요청 제공동적 콘텐츠를 위해 API를 통해 Laravel CMS에 연결하는 모바일 앱(또는 웹사이트) 구축을 고려하십시오. 이제 앱은 CMS에서 번역된 콘텐츠를 받을 것으로 예상되는 다국어 앱이 될 수 있습니다. 일반적으로 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.