laravel 의존 주입 분석
9855 단어 PHP
보통 우리 의 호출 은 다음 과 같다.
$config = $container->make('config');
$connection = new Connection($this->config);
이해 하기 쉽다. 이러한 장점 은 바로 new 의 실례 를 직접 사용 하지 않 아 도 된다 는 것 이다. 방법의 값 은 변 함 이 없고 여러 곳 에서 이 실례 를 공유 할 수 있다.
그러나 이것 은 주입 에 의존 하 는 것 과 어떤 관계 가 있 습 니까? 진정한 의존 주입 은 방법 에 어떠한 매개 변수 값 도 전달 하지 않 고 방법 매개 변수 유형 만 가리 키 고 코드 자동 검색 관 계 는 자동 주입 에 의존 합 니 다.
이 특성 은 laravel 의 Controller, Job 등에 서 다음 과 같이 나타 날 수 있 습 니 다.
class TestController extends Controller
{
public function anyConsole(Request $request, Auth $input)
{
//todo
}
}
우 리 는 그 가 어떻게 자동 의존 주입 을 실현 하 는 지 보 자.
index.php
에서 호출 Kernel
하고 다 층 Kernel
파 이 프 를 통 해 호출 한 다음 에 Router
까지 다 층 중간 부품 파 이 프 를 통 해 호출 된다.최종 위치 지정Illuminate/Routing/Route.php
124 번 째 줄.public function run(Request $request)
{
$this->container = $this->container ?: new Container;
try {
if (! is_string($this->action['uses'])) {
return $this->runCallable($request);
}
if ($this->customDispatcherIsBound()) {
return $this->runWithCustomDispatcher($request);
}
return $this->runController($request);
} catch (HttpResponseException $e) {
return $e->getResponse();
}
}
$this->action['uses']
(예 를 들 어 \App\Http\Controller\Datacenter\RealTimeController@anyConsole
문자열 여 부 를 판단 하고 $this->customDispatcherIsBound
사용자 정의 경로 가 연결 되 어 있 는 지 여 부 를 판단 합 니 다.그리고 뛰 어 $this->runController($request)
.protected function runController(Request $request)
{
list($class, $method) = explode('@', $this->action['uses']);
$parameters = $this->resolveClassMethodDependencies(
$this->parametersWithoutNulls(), $class, $method
);
if (! method_exists($instance = $this->container->make($class), $method)) {
throw new NotFoundHttpException;
}
return call_user_func_array([$instance, $method], $parameters);
}
$this->resolveClassMethodDependencies
이 방법 은 이름 만 봐 도 우리 가 찾 는 방법 임 을 알 수 있다.$this->parametersWithoutNulls()
은 빈 문 자 를 걸 러 내 는 것 입 니 다. $class
, $method
은 각각 다음 과 같 습 니 다. \App\Http\Controller\Datacenter\RealTimeController
과 anyConsole
.protected function resolveClassMethodDependencies(array $parameters, $instance, $method)
{
if (! method_exists($instance, $method)) {
return $parameters;
}
return $this->resolveMethodDependencies(
$parameters, new ReflectionMethod($instance, $method)
);
}
new ReflectionMethod($instance, $method)
유형 을 얻 는 방법의 반사 대상 으로 문 서 를 참조 합 니 다.http://www.php.net/manual/zh/class.reflectionmethod.php 다음은
Illuminate/Routing/RouteDependencyResolverTrait.php
54 번 째 줄 로 넘 어 갑 니 다.public function resolveMethodDependencies(array $parameters, ReflectionFunctionAbstract $reflector)
{
$originalParameters = $parameters;
foreach ($reflector->getParameters() as $key => $parameter) {
$instance = $this->transformDependency(
$parameter, $parameters, $originalParameters
);
if (! is_null($instance)) {
$this->spliceIntoParameters($parameters, $key, $instance);
}
}
return $parameters;
}
반사 류 방법 을 통 해 클래스 매개 변수 배열 을 얻 은 다음 에
$this->transformDependency
방법 에 전달 합 니 다.인 스 턴 스 가 가 져 오지 못 하면 호출 $this->spliceIntoParameters
에서 이 인 자 를 알 수 있 습 니 다.protected function transformDependency(ReflectionParameter $parameter, $parameters, $originalParameters)
{
$class = $parameter->getClass();
if ($class && ! $this->alreadyInParameters($class->name, $parameters)) {
return $this->container->make($class->name);
}
}
마침내 용기 의 그림 자 를 보 았 다. 그래, 최종 대상 은 용기 의
make
방법 으로 꺼 냈 다.이로써 매개 변 수 는 구 조 된 후에 최종 적 으로 runController
방법의 call_user_func_array
에 의 해 회 조 될 것 이다.요약: 1. 주입 원리 에 의존 하 는 것 은 바로 유형 방법 으로 반사 하여 매개 변수 유형 을 얻 은 다음 에 용기 구 조 를 이용 하여 인 스 턴 스 를 잘 만 드 는 것 이다.그리고 리 셋 함 수 를 사용 하여 리 셋 합 니 다.2. 주입 대상 구조 함수 에 인자 가 있 으 면 안 됩 니 다.그렇지 않 으 면 잘못 보고 할 것 이다.
Missing argument 1
3. 주입 에 의존 하 는 것 이 좋 지만 Router 류 에서 조정 해 야 합 니 다. 그렇지 않 으 면 new 방식 으로 주입 할 수 없습니다.그래서 왜 Controller, Job 류 만 이 기능 을 사용 할 수 있 습 니까?
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
laravel에 yo에서 angularJs&coffeescript를 사용할 수 있도록 한다.먼저 yo 명령을 사용할 수 있어야하므로 아래에서 설치 global에 설치한 곳에서 laravel의 프로젝트 루트로 이동. 클라이언트 코드를 관리하는 디렉토리를 만들고 이동합니다. 클라이언트 환경 만들기 이것으로 히...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.