Dans Laravel, le principe d'implémentation de l'injection de dépendances consiste à utiliser la réflexion de la méthode de classe pour obtenir le type de paramètre, puis à utiliser le conteneur pour construire l'instance, puis à utiliser la fonction de rappel pour l'appeler. Le constructeur d'objet injecté ne peut pas avoir de paramètres ; , sinon une erreur sera signalée et l'injection de dépendances doit être appelée par la classe Router, sinon l'injection ne peut pas être réalisée directement en utilisant la nouvelle méthode.
L'environnement d'exploitation de cet article : système Windows 10, Laravel version 6, ordinateur Dell G3.
Le conteneur laravel inclut l'inversion de contrôle et l'injection de dépendances. Pour l'utiliser, vous devez d'abord lier l'objet, et vous pouvez directement utiliser make pour le récupérer en cas de besoin.
Pour une analyse spécifique, veuillez vous référer à : http://laravelacademy.org/post/769.html
Habituellement, nos appels sont les suivants.
$config = $container->make('config'); $connection = new Connection($this->config);
C'est plus facile à comprendre. L'avantage de ceci est que vous n'avez pas besoin de créer directement une instance. Il n'y a aucun changement dans la valeur transmise par la méthode. Vous pouvez également partager cette instance à plusieurs endroits.
Mais qu'est-ce que cela a à voir avec l'injection de dépendances ? La véritable injection de dépendances ne nécessite pas de transmettre de valeurs de paramètre à la méthode. Il vous suffit de spécifier le type de paramètre de la méthode, et le code trouvera automatiquement la relation et l'injectera automatiquement. la dépendance.
Cette fonctionnalité peut être reflétée dans le contrôleur, le travail, etc. de Laravel, comme suit :
class TestController extends Controller { public function anyConsole(Request $request, Auth $input) { //todo } }
Voyons comment elle implémente l'injection automatique de dépendances :
Le noyau est appelé par index.PHP, appelé via multicouche Les pipelines du noyau, puis vers le routeur, appellent via un pipeline middleware multicouche. Enfin situé à la ligne 124 de
Illuminate/Routing/Route.php.
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(); } }
Déterminez si $this->action['uses'] (ligne de format telle que : AppHttpControllerDatacenterRealTimeController@anyConsole) est une chaîne, $this->customDispatcherIsBound détermine si une route définie par l'utilisateur est liée. Passez ensuite à $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 Dès que vous regardez le nom, vous pouvez dire que cette méthode est la méthode que nous recherchons. $this->parametersWithoutNulls() consiste à filtrer les caractères nuls $class et $method sont respectivement les suivants : AppHttpControllerDatacenterRealTimeController et 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) est l'objet de réflexion qui obtient la méthode de classe, voir le document : http://www.php.net/manual/zh/class.reflectionmethod.php
Aller à Illuminate ci-dessous /Routing/RouteDependencyResolverTrait.php ligne 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; }
Obtenez le tableau de paramètres de classe via la méthode de classe de réflexion, puis parcourez-le et transmettez-le à la méthode $this->transformDependency. Si l'instance ne peut pas être obtenue, appelez $this->spliceIntoParameters pour effacer les paramètres.
protected function transformDependency(ReflectionParameter $parameter, $parameters, $originalParameters) { $class = $parameter->getClass(); if ($class && ! $this->alreadyInParameters($class->name, $parameters)) { return $this->container->make($class->name); } }
Enfin j'ai vu l'ombre du conteneur Oui, l'objet final a été retiré via la méthode make du conteneur. À ce stade, les paramètres sont construits et seront éventuellement rappelés par le call_user_func_array de la méthode runController.
Résumé :
Le principe de l'injection de dépendances est en fait d'utiliser la réflexion de la méthode de classe pour obtenir le type de paramètre, puis d'utiliser le conteneur pour construire l'instance. Utilisez ensuite la fonction de rappel pour l'appeler.
Le constructeur d'objet injecté ne peut pas avoir de paramètres. Sinon, une erreur sera signalée. Argument manquant 1
L'injection de dépendances est bonne, mais elle doit être invoquée par la classe Router, sinon l'injection ne peut pas être réalisée directement en utilisant la nouvelle méthode. C'est pourquoi seules les classes Controller et Job peuvent utiliser cette fonctionnalité.
【Recommandation associée : tutoriel vidéo Laravel】
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!