Was ist Abhängigkeitsinjektion in PHP und wie wird sie verwendet?
Eine beliebte und bekannte Methode der Softwareentwicklung heißt Dependency Injection. Sie erleichtert den Ablauf und stellt sicher, dass Ihre Software immer Zugriff auf die benötigten Tools hat. Viele versuchen, diese Methode recht komplex klingen zu lassen, aber das ist es wirklich nicht.
Lassen Sie uns untersuchen, was Abhängigkeitsinjektion ist, wie sie funktioniert und wie sie Ihrer Software zugute kommt.
Was ist Abhängigkeitsinjektion?
Eine großartige Analogie für die Abhängigkeitsinjektion ist ein Mitarbeiter mit einem Toolkit, der die Software während der Verarbeitung mitverfolgt und so einen reibungslosen Ablauf gewährleistet. Das Toolkit kann alle möglichen Dinge enthalten, einschließlich Variablen, Arrays, Objekte , Abschlüsse und alles andere, was zur Ausführung der vorliegenden Aufgabe erforderlich ist.
Wenn der Mitarbeiter eine neue Aufgabe (z. B. Klasse oder Methode) startet, werden die erforderlichen Anforderungen geprüft und ohne nachzudenken die verschiedenen Tools herausgezogen, die zur Ausführung des Auftrags erforderlich sind. Dies ist die Abhängigkeitsinjektion auf den Punkt gebracht.
Sie können Ihr Toolkit mit allem füllen, was Sie benötigen. Geben Sie dann in den Klassen und Methoden der Software die Tools an, die Sie benötigen, und diese sind automatisch für Sie da.
Installieren Sie den Apex-Container
Es gibt viele verschiedene Implementierungen, aber alle funktionieren grundsätzlich gleich, und wir werden den Apex-Container verwenden, da er einfach und unkompliziert ist. Es wird davon ausgegangen, dass Sie PHP bereits installiert haben, und Sie können mit dem folgenden Befehl überprüfen, ob Composer installiert ist oder nicht:
composer --version
Wenn Sie den Fehler "Befehl nicht gefunden" erhalten, können Sie Composer mit dem folgenden Befehl installieren:
sudo curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer
Erstellen Sie nun ein leeres Verzeichnis und führen Sie im Verzeichnis die folgenden Befehle aus:
composer require apex/container
composer require twig/twig
Dadurch werden sowohl der Apex-Container als auch die beliebte Twig-Template-Engine heruntergeladen, die in den folgenden Beispielen verwendet wird. Beide befinden sich im Unterverzeichnis / vendor /.
Injizieren Sie Ihre Werkzeuge
Erstellen wir eine schnelle Klasse namens Car mit dem folgenden Code:
<?php
use TwigLoaderArrayLoader;
class Car
{
public function __construct(
public string $model,
public string $color,
public ArrayLoader $db
) {
echo "I'm a $color $model and have a " . $db::class . "
";
}
}
Dies ist eine einfache Klasse mit zwei Eigenschaften, der Marke und der Farbe eines Autos, und lädt die 'ArrayLoader'-Klasse von Twig. Speichern Sie es als car.php und bereiten Sie sich darauf vor, die Magie der Abhängigkeitsinjektion zu nutzen. Öffnen Sie eine weitere leere Datei und fügen Sie den folgenden Code hinzu:
<?php
use ApexContainerContainer;
// Load Composer packages, and the car.php file
require_once(__DIR__ . '/vendor/autoload.php');
require_once(__DIR__ . '/car.php');
// Create container, and add a couple tools
$cntr = new Container(use_attributes: true);
$cntr->set('model', 'Jaguar');
$cntr->set('color', 'silver');
// Create our car object
$car = $cntr->make('Car');
$car2 = $cntr->make('car', ['color' => 'red']);
Speichern Sie diesen Code und führen Sie ihn im Terminal aus. Die Ergebnisse sind:
I'm a silver Jaguar and have a TwigLoaderArrayLoader
I'm a red Jaguar and have a TwigLoaderArrayLoader
Im obigen Code haben Sie den Container (dh das Toolkit) instanziiert und ein paar Werkzeuge hinzugefügt, die Farbe und die Marke eines Autos. Anstatt das Autoobjekt mit dem normalen neuen Auto () zu erstellen ; wurde über die Methode make () des Containers erstellt. Dies ging zuerst durch die Klasse, um die Anforderungen zu überprüfen, dann zu prüfen, welche Gegenstände (dh Werkzeuge) wir zur Verfügung hatten, und sie in die Klasse zu injizieren, bevor sie zurückgegeben wurden.
Sie werden die Verwendungsdeklaration oben in der Datei für den ArrayLoader bemerken, und das dritte Argument im Konstruktor fordert auch einen ArrayLoader an . Als der Container die Anforderungen der Klasse betrachtete, bemerkte er beide Aspekte, erstellte automatisch eine Instanz von ArrayLoader `und injizierte sie in den Konstruktor. Dies wird als automatische Verkabelung bezeichnet.
Erweitern mit Attributinjektion
Wenn wir noch einen Schritt weiter gehen, können wir nicht nur in den Konstruktor injizieren, sondern auch direkt über Attribute in Eigenschaften injizieren. Ändern Sie die Fahrzeugdatei und ändern Sie sie in:
<?php
use TwigLoaderArrayLoader;
use ApexContainerContainer;
class Car
{
#[Inject(Container::class)]
public Container $cntr;
public function __construct(
public string $model,
public string $color,
public ArrayLoader $db
) {
echo "I'm a $color $model and have a " . $db::class . "
";
}
function getCost()
{
echo "Class is " . $this->cntr::class . "
";
}
}
Die einzigen Änderungen waren, dass eine neue Verwendungsdeklaration hinzugefügt wurde, die Eigenschaft mit dem Attribut der Container-Klasse hinzugefügt wurde und wir eine neue Funktion getCost () hinzugefügt haben. Fügen Sie am Ende des zuvor ausgeführten Testcodes die folgende Zeile hinzu:
$car->getCost();
Führen Sie nun den Code erneut aus, und die Ergebnisse sind:
I'm a silver Jaguar and have a TwigLoaderArrayLoader
I'm a red Jaguar and have a TwigLoaderArrayLoader
Class is ApexContainerContainer
Dieses Mal, als die car.php- Klasse geladen wurde, überprüfte der Container auch seine Eigenschaften, bemerkte das Inject- Attribut, das die Container-Klasse aufforderte , und injizierte eine Instanz davon. Das Injizieren über Attribute auf diese Weise wird manchmal bevorzugt, da dies dazu beiträgt , die Dinge sauberer und lesbarer zu halten.
Holen Sie sich Ihre eigenen Werkzeuge
Was passiert, wenn Sie einen Artikel selbst aus dem Container abrufen möchten, anstatt immer Artikel zu injizieren? Dies kann leicht mit der get () -Methode des Containers durchgeführt werden. Ändern Sie in der Datei car.php die zuvor hinzugefügte Funktion getCost () mit:
function getCost()
{
$price = $this->cntr->get('car_price');
echo "The price is $price
";
}
Fügen Sie nun innerhalb des Testcodes, den Sie ausgeführt haben, irgendwo vor der Zeile, die getCost () aufruft , eine Zeile hinzu, z.
$cntr->set('car_price', 24995);
Führen Sie nun den Code aus und die Ergebnisse sind:
I'm a silver Jaguar and have a TwigLoaderArrayLoader
I'm a red Jaguar and have a TwigLoaderArrayLoader
Price is 24999
Sie müssen Ihre Artikel nicht unbedingt injizieren und können mit der oben gezeigten Methode get () immer problemlos das finden, was Sie benötigen.
Mit Abhängigkeitsinjektion vorwärts gehen
Sie haben jetzt einen guten Überblick darüber, was Abhängigkeitsinjektion genau ist und wie sie funktioniert. Auch hier ist das Obige nur eine von vielen Implementierungen, aber alle Implementierungen funktionieren auf die gleiche Weise mit den Methoden get () / set () / make () .
Die Abhängigkeitsinjektion bietet jedoch noch mehr, wie z. B. die Definition der Definitionsdatei und der Methodeninjektion. Bei Interesse lesen Sie bitte das Apex Container-Handbuch oder andere Implementierungen.