Interpretation des Laravel-Servicecontainers (IocContainer)
Dieser Artikel stellt hauptsächlich die Interpretation des Laravel-Servicecontainers (IocContainer) vor, der einen gewissen Referenzwert hat. Jetzt kann ich ihn mit allen teilen. Freunde in Not können sich darauf beziehen.
Der Kern von Laravel ist IocContainer. Dokument Es wird als „Service-Container“ bezeichnet. Der Service-Container ist ein leistungsstarkes Tool zum Verwalten von Klassenabhängigkeiten und zur Durchführung der Abhängigkeitsinjektion. Die Funktionsmodule in Laravel wie Route, Eloquent ORM, Request, Response usw. beziehen sich tatsächlich auf Bereitgestellt von Kernunabhängige Klassenmodule. Diese Klassen sind tatsächlich für den Laravel-Service-Container von der Registrierung bis zur Instanziierung verantwortlich und werden schließlich von uns verwendet.
Wenn Sie keine klare Vorstellung davon haben, was ein Service-Container ist, empfehle ich einen Blog-Beitrag, um mehr über die Besonderheiten des Service-Containers zu erfahren: Laravel's magischer Service-Container
Es gibt zwei Konzepte im Service-Container: Inversion of Control (IOC) und Dependency Injection (DI):
Dependency Injection und Inversion of Control sind unterschiedliche Beschreibungen derselben Sache und sie beschreiben sie aus unterschiedlichen Perspektiven . Die Abhängigkeitsinjektion wird aus der Perspektive der Anwendung beschrieben. Die Anwendung ist auf den Container angewiesen, um die benötigten externen Ressourcen zu erstellen und zu injizieren. Die Umkehrung der Kontrolle wird aus der Perspektive des Containers beschrieben. Der Container steuert die Anwendung, und der Container injiziert umgekehrt die von der Anwendung benötigten externen Ressourcen.
In Laravel bindet das Framework seine verschiedenen Dienste an den Service-Container. Wir können auch benutzerdefinierte Dienste an den Container binden. Wenn eine Anwendung einen bestimmten Dienst verwenden muss, löst der Dienstcontainer den Dienst auf, löst automatisch die Abhängigkeiten zwischen Diensten auf und übergibt ihn dann zur Verwendung an die Anwendung.
In diesem Artikel wird erläutert, wie Dienstbindung und -analyse in Laravel implementiert werden.
Dienstbindung
Häufig verwendete Methoden zum Binden von Diensten an Container sind Instanz, Bindung, Singleton und Alias. Schauen wir sie uns einzeln an.
Instanz
bindet ein vorhandenes Objekt an den Dienstcontainer. Wenn der Dienst anschließend nach Namen aufgelöst wird, gibt der Container immer die gebundene Instanz zurück.
$api = new HelpSpot\API(new HttpClient); $this->app->instance('HelpSpot\Api', $api);
registriert das Objekt im Attribut $instnces des Service-Containers
[ 'HelpSpot\Api' => $api//$api是API类的对象,这里简写了 ]
bind
Bindet den Service an den Service-Container
Es gibt drei Bindungsmethoden:
1.绑定自身 $this->app->bind('HelpSpot\API', null); 2.绑定闭包 $this->app->bind('HelpSpot\API', function () { return new HelpSpot\API(); });//闭包直接提供类实现方式 $this->app->bind('HelpSpot\API', function ($app) { return new HelpSpot\API($app->make('HttpClient')); });//闭包返回需要依赖注入的类 3. 绑定接口和实现 $this->app->bind('Illuminate\Tests\Container\IContainerContractStub', 'Illuminate\Tests\Container\ContainerImplementationStub');
Im ersten Fall wird innerhalb der Bindungsmethode tatsächlich ein Abschluss für den Dienst über getClosure()
generiert, bevor der Dienst gebunden wird Verfahren.
public function bind($abstract, $concrete = null, $shared = false) { $abstract = $this->normalize($abstract); $concrete = $this->normalize($concrete); //如果$abstract为数组类似['Illuminate/ServiceName' => 'service_alias'] //抽取别名"service_alias"并且注册到$aliases[]中 //注意:数组绑定别名的方式在5.4中被移除,别名绑定请使用下面的alias方法 if (is_array($abstract)) { list($abstract, $alias) = $this->extractAlias($abstract); $this->alias($abstract, $alias); } $this->dropStaleInstances($abstract); if (is_null($concrete)) { $concrete = $abstract; } //如果只提供$abstract,则在这里为其生成concrete闭包 if (! $concrete instanceof Closure) { $concrete = $this->getClosure($abstract, $concrete); } $this->bindings[$abstract] = compact('concrete', 'shared'); if ($this->resolved($abstract)) { $this->rebound($abstract); } } protected function getClosure($abstract, $concrete) { // $c 就是$container,即服务容器,会在回调时传递给这个变量 return function ($c, $parameters = []) use ($abstract, $concrete) { $method = ($abstract == $concrete) ? 'build' : 'make'; return $c->$method($concrete, $parameters); }; }
bind registriert den Dienst im $bindings-Attribut des Service-Containers, ähnlich wie folgt:
$bindings = [ 'HelpSpot\API' => [//闭包绑定 'concrete' => function ($app, $paramters = []) { return $app->build('HelpSpot\API'); }, 'shared' => false//如果是singleton绑定,这个值为true ] 'Illuminate\Tests\Container\IContainerContractStub' => [//接口实现绑定 'concrete' => 'Illuminate\Tests\Container\ContainerImplementationStub', 'shared' => false ] ]
Singleton
public function singleton($abstract, $concrete = null) { $this->bind($abstract, $concrete, true); }
Singleton-Methode ist eine Variante der Bind-Methode. und um eine zu binden, muss die Klasse oder Schnittstelle nur einmal in den Container aufgelöst werden, und dann gibt der Dienst dieselbe Instanz für nachfolgende Aufrufe an den Container zurück
Alias
Registrieren Sie den Dienst und den Dienstalias bei der Container:
public function alias($abstract, $alias) { $this->aliases[$alias] = $this->normalize($abstract); }
Die Alias-Methode ist in der oben erwähnten Bindungsmethode nützlich. Sie registriert die entsprechende Beziehung zwischen dem Service-Alias und der Service-Klasse im Attribut $aliases des Service-Containers.
Zum Beispiel:
$this->app->alias('\Illuminate\ServiceName', 'service_alias');
Nach dem Binden des Dienstes können Sie das Dienstobjekt bei Verwendung über
$this->app->make('service_alias');
analysieren, sodass Sie bei der Verwendung keine längeren Klassennamen schreiben müssen Die Erfahrung mit der Make-Methode wurde erheblich verbessert.
Service-Analyse
make: Analysieren Sie das Serviceobjekt aus dem Service-Container. Diese Methode empfängt den Klassennamen oder Schnittstellennamen, den Sie analysieren möchten, als Parameter
/** * Resolve the given type from the container. * * @param string $abstract * @param array $parameters * @return mixed */ public function make($abstract, array $parameters = []) { //getAlias方法会假定$abstract是绑定的别名,从$aliases找到映射的真实类型名 //如果没有映射则$abstract即为真实类型名,将$abstract原样返回 $abstract = $this->getAlias($this->normalize($abstract)); // 如果服务是通过instance()方式绑定的,就直接解析返回绑定的service if (isset($this->instances[$abstract])) { return $this->instances[$abstract]; } // 获取$abstract接口对应的$concrete(接口的实现) $concrete = $this->getConcrete($abstract); if ($this->isBuildable($concrete, $abstract)) { $object = $this->build($concrete, $parameters); } else { //如果时接口实现这种绑定方式,通过接口拿到实现后需要再make一次才能 //满足isBuildable的条件 ($abstract === $concrete) $object = $this->make($concrete, $parameters); } foreach ($this->getExtenders($abstract) as $extender) { $object = $extender($object, $this); } //如果服务是以singleton方式注册进来的则,把构建好的服务对象放到$instances里, //避免下次使用时重新构建 if ($this->isShared($abstract)) { $this->instances[$abstract] = $object; } $this->fireResolvingCallbacks($abstract, $object); $this->resolved[$abstract] = true; return $object; } protected function getConcrete($abstract) { if (! is_null($concrete = $this->getContextualConcrete($abstract))) { return $concrete; } // 如果是$abstract之前没有注册类实现到服务容器里,则服务容器会认为$abstract本身就是接口的类实现 if (! isset($this->bindings[$abstract])) { return $abstract; } return $this->bindings[$abstract]['concrete']; } protected function isBuildable($concrete, $abstract) { return $concrete === $abstract || $concrete instanceof Closure; }
Durch Aufruf make Nachdem wir die Methode aussortiert hatten, stellten wir fest, dass die Funktion der Build-Methode darin besteht, das analysierte Serviceobjekt zu erstellen. Schauen wir uns den spezifischen Prozess der Objekterstellung an. (Die Reflexion von PHP-Klassen wird während des Konstruktionsprozesses verwendet, um die Abhängigkeitsinjektion von Diensten zu implementieren.)
public function build($concrete, array $parameters = []) { // 如果是闭包直接执行闭包并返回(对应闭包绑定) if ($concrete instanceof Closure) { return $concrete($this, $parameters); } // 使用反射ReflectionClass来对实现类进行反向工程 $reflector = new ReflectionClass($concrete); // 如果不能实例化,这应该是接口或抽象类,再或者就是构造函数是private的 if (! $reflector->isInstantiable()) { if (! empty($this->buildStack)) { $previous = implode(', ', $this->buildStack); $message = "Target [$concrete] is not instantiable while building [$previous]."; } else { $message = "Target [$concrete] is not instantiable."; } throw new BindingResolutionException($message); } $this->buildStack[] = $concrete; // 获取构造函数 $constructor = $reflector->getConstructor(); // 如果构造函数是空,说明没有任何依赖,直接new返回 if (is_null($constructor)) { array_pop($this->buildStack); return new $concrete; } // 获取构造函数的依赖(形参),返回一组ReflectionParameter对象组成的数组表示每一个参数 $dependencies = $constructor->getParameters(); $parameters = $this->keyParametersByArgument( $dependencies, $parameters ); // 构建构造函数需要的依赖 $instances = $this->getDependencies( $dependencies, $parameters ); array_pop($this->buildStack); return $reflector->newInstanceArgs($instances); } //获取依赖 protected function getDependencies(array $parameters, array $primitives = []) { $dependencies = []; foreach ($parameters as $parameter) { $dependency = $parameter->getClass(); // 某一依赖值在$primitives中(即build方法的$parameters参数)已提供 // $parameter->name返回参数名 if (array_key_exists($parameter->name, $primitives)) { $dependencies[] = $primitives[$parameter->name]; } elseif (is_null($dependency)) { // 参数的ReflectionClass为null,说明是基本类型,如'int','string' $dependencies[] = $this->resolveNonClass($parameter); } else { // 参数是一个类的对象, 则用resolveClass去把对象解析出来 $dependencies[] = $this->resolveClass($parameter); } } return $dependencies; } //解析出依赖类的对象 protected function resolveClass(ReflectionParameter $parameter) { try { // $parameter->getClass()->name返回的是类名(参数在typehint里声明的类型) // 然后递归继续make(在make时发现依赖类还有其他依赖,那么会继续make依赖的依赖 // 直到所有依赖都被解决了build才结束) return $this->make($parameter->getClass()->name); } catch (BindingResolutionException $e) { if ($parameter->isOptional()) { return $parameter->getDefaultValue(); } throw $e; } }
Der Service-Container ist der Kern von Laravel. Er kann die Abhängigkeiten zwischen Objekten für uns durch Abhängigkeitsinjektion und Kontrolle lösen Inversion, spezifische Verhaltensweisen werden extern definiert (Route, Eloquent, das sind externe Module, und sie definieren ihre eigenen Verhaltensspezifikationen. Der Service-Container ist für diese Klassen von der Registrierung bis zur Instanziierung für Ihre Verwendung verantwortlich).
Damit eine Klasse von einem Container extrahiert werden kann, muss sie zunächst beim Container registriert werden. Da Laravel diesen Container als Service-Container bezeichnet, müssen wir, wenn wir einen Service benötigen, zuerst den Service registrieren und an den Container binden. Dann ist das Ding, das den Service bereitstellt und den Service an den Container bindet, der Service-Provider (ServiceProvider). Der Dienstanbieter ist hauptsächlich in zwei Teile unterteilt: Registrieren (Registrierung) und Booten (Booten, Initialisieren). Informationen zum Inhalt des Laravel-Dienstanbieters finden Sie in einer anderen Laravel-Kerninterpretation – Dienstanbieter (ServiceProvider).
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website.
Verwandte Empfehlungen:
Laravel Core Interpretation Request
Das obige ist der detaillierte Inhalt vonInterpretation des Laravel-Servicecontainers (IocContainer). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Die neuesten Versionen von Laravel 9 und CodeIgniter 4 bieten aktualisierte Funktionen und Verbesserungen. Laravel9 übernimmt die MVC-Architektur und bietet Funktionen wie Datenbankmigration, Authentifizierung und Template-Engine. CodeIgniter4 nutzt die HMVC-Architektur, um Routing, ORM und Caching bereitzustellen. In Bezug auf die Leistung sorgen das auf Dienstanbietern basierende Designmuster von Laravel9 und das leichte Framework von CodeIgniter4 für eine hervorragende Leistung. In praktischen Anwendungen eignet sich Laravel9 für komplexe Projekte, die Flexibilität und leistungsstarke Funktionen erfordern, während CodeIgniter4 für schnelle Entwicklung und kleine Anwendungen geeignet ist.

Vergleichen Sie die Datenverarbeitungsfunktionen von Laravel und CodeIgniter: ORM: Laravel verwendet EloquentORM, das eine relationale Klassen-Objekt-Zuordnung bereitstellt, während CodeIgniter ActiveRecord verwendet, um das Datenbankmodell als Unterklasse von PHP-Klassen darzustellen. Abfrage-Builder: Laravel verfügt über eine flexible verkettete Abfrage-API, während der Abfrage-Builder von CodeIgniter einfacher und Array-basiert ist. Datenvalidierung: Laravel bietet eine Validator-Klasse, die benutzerdefinierte Validierungsregeln unterstützt, während CodeIgniter über weniger integrierte Validierungsfunktionen verfügt und eine manuelle Codierung benutzerdefinierter Regeln erfordert. Praxisfall: Beispiel einer Benutzerregistrierung zeigt Lar

Laravel – Artisan Commands – Laravel 5.7 bietet eine neue Möglichkeit, neue Befehle zu behandeln und zu testen. Es enthält eine neue Funktion zum Testen von Handwerkerbefehlen und die Demonstration wird unten erwähnt?

Für Anfänger bietet CodeIgniter eine sanftere Lernkurve und weniger Funktionen, deckt aber die Grundbedürfnisse ab. Laravel bietet einen größeren Funktionsumfang, weist jedoch eine etwas steilere Lernkurve auf. In Bezug auf die Leistung schneiden sowohl Laravel als auch CodeIgniter gut ab. Laravel verfügt über eine umfangreichere Dokumentation und aktive Community-Unterstützung, während CodeIgniter einfacher und leichtgewichtiger ist und über starke Sicherheitsfunktionen verfügt. Im praktischen Fall der Erstellung einer Blogging-Anwendung vereinfacht EloquentORM von Laravel die Datenmanipulation, während CodeIgniter mehr manuelle Konfiguration erfordert.

Bei der Auswahl eines Frameworks für große Projekte haben Laravel und CodeIgniter jeweils ihre eigenen Vorteile. Laravel ist für Anwendungen auf Unternehmensebene konzipiert und bietet modularen Aufbau, Abhängigkeitsinjektion und einen leistungsstarken Funktionsumfang. CodeIgniter ist ein leichtes Framework, das sich eher für kleine bis mittelgroße Projekte eignet und Wert auf Geschwindigkeit und Benutzerfreundlichkeit legt. Für große Projekte mit komplexen Anforderungen und einer großen Anzahl von Benutzern sind die Leistung und Skalierbarkeit von Laravel besser geeignet. Für einfache Projekte oder Situationen mit begrenzten Ressourcen sind die leichten und schnellen Entwicklungsfunktionen von CodeIgniter idealer.

Für kleine Projekte eignet sich Laravel, für größere Projekte, die starke Funktionalität und Sicherheit erfordern. CodeIgniter eignet sich für sehr kleine Projekte, die geringes Gewicht und Benutzerfreundlichkeit erfordern.

Die Microservice-Architektur nutzt PHP-Frameworks (wie Symfony und Laravel) zur Implementierung von Microservices und folgt RESTful-Prinzipien und Standarddatenformaten zum Entwerfen von APIs. Microservices kommunizieren über Nachrichtenwarteschlangen, HTTP-Anfragen oder gRPC und nutzen Tools wie Prometheus und ELKStack zur Überwachung und Fehlerbehebung.

Vergleichen Sie Laravel's Blade und die Twig-Vorlagen-Engine von CodeIgniter und wählen Sie je nach Projektanforderungen und persönlichen Vorlieben: Blade basiert auf der MVC-Syntax, die eine gute Codeorganisation und Vorlagenvererbung fördert. Twig ist eine Bibliothek eines Drittanbieters, die flexible Syntax, leistungsstarke Filter, erweiterten Support und eine Sicherheits-Sandbox bietet.
