Heim > Backend-Entwicklung > PHP-Tutorial > PHP Master | Abhängigkeitsinjektion mit Pickel

PHP Master | Abhängigkeitsinjektion mit Pickel

Christopher Nolan
Freigeben: 2025-02-24 08:57:10
Original
513 Leute haben es durchsucht

PHP Master | Dependency Injection with Pimple

Kernpunkte

  • Abhängigkeitsinjektion ist ein Schlüsselkonzept für die Anwendungsentwicklung. Durch die Injektion von Abhängigkeiten in Module, anstatt sie zu harten, können Sie effizientere Code schreiben.
  • Pimple ist ein einfacher Abhängigkeitsinjektionsbehälter, der die Abschluss von PHP verwendet, um Abhängigkeiten auf überschaubare Weise zu definieren und dazu beitragen, Ihren Code aufrechtzuerhalten.
  • Die beiden Haupttechniken für die Injektion von Abhängigkeiten sind Konstruktor-basierte Abhängigkeitsinjektion und setterbasierte Injektion mit jeweils eigenen Vor- und Nachteilen.
  • Pimple unterstützt das Trockenprinzip der Softwareentwicklung, indem es als Container fungiert, der Abhängigkeiten definiert, wodurch die Duplikation vermieden wird und die Verwaltung und Zentralisierung von Diensten in Anwendungen erleichtert.
  • Pimple bietet auch erweiterte Funktionen, wie die Möglichkeit, dieselbe Instanz mithilfe gemeinsamer Objekte zurückzugeben, und die Fähigkeit, vorhandene Verschlüsse dynamisch zu ändern, ohne die ursprüngliche Implementierung zu beeinflussen.

In der Anwendungsentwicklung versuchen wir, eigenständige Module zu erstellen, um Code in zukünftigen Projekten wiederzuverwenden. Das Erstellen von völlig unabhängigen Modulen, die nützliche Funktionen liefern, ist jedoch schwierig. Hier ist die Abhängigkeitsinjektion nützlich, da wir die Abhängigkeiten, die benötigt werden, damit der Code benötigt wird, ohne festen Code in das Modul zu funktionieren. Pimple ist ein einfacher Abhängigkeitsinjektionsbehälter, in dem PHP -Verschluss verwendet wird, um Abhängigkeiten auf überschaubare Weise zu definieren. In diesem Artikel werden wir das Problem hart codierter Abhängigkeiten, die Lösung von Abhängigkeitsinjektionen untersuchen und wie man Pimple verwendet, um die Aufrechterhaltung der Code-Nebel-Abhängigkeitsinjektion zu erleichtern.

Spezifische Abhängigkeiten Ausgabe

Beim Schreiben von Anwendungen verwenden wir viele PHP -Klassen. Eine Klasse muss möglicherweise Methoden eines oder mehrerer anderer Klassen aufrufen, um die erwartete Funktionalität zu liefern. Wir sagen, dass die erste Klasse von anderen Klassen abhängt. Zum Beispiel:

<?php
class A
{
    public function a1() {
        $b = new B();
        $b->b1();
    }
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

Klasse A hängt von Klasse B. ab. Wenn die Klasse B nicht verfügbar ist, funktioniert der obige Code nicht. Darüber hinaus haben wir jedes Mal, wenn wir die Erstellung eines Objekts in der Klasse härten, spezifische Abhängigkeiten von der Klasse. Spezifische Abhängigkeiten sind ein Hindernis für das Schreiben von Testable Code. Ein besserer Ansatz ist es, ein Objekt der Klasse B der Klasse B zu liefern. A. Diese Objekte können mit der Konstruktor- oder Settermethode von A bereitgestellt werden. Bevor wir weiter diskutieren, schauen wir uns ein realistischeres Szenario an.

Inhalt auf sozialen Netzwerk -Websites teilen, ist heutzutage sehr häufig, und die meisten Websites zeigen ihre sozialen Profil -Feeds auf ihren Websites direkt an. Angenommen, wir haben eine Klasse namens SocialFeeds, die Feeds von sozialen Websites wie Twitter, Facebook, Google usw. generiert. Erstellen Sie separate Klassen, um jede dieser Dienste zu verarbeiten. Hier werden wir uns den Klassen -Twitterservice ansehen, der mit Twitter interagiert. Die SocialFeeds -Klasse verwendet TwitterService, um Twitter -Feeds anzufordern. TwitterService interagiert mit der Datenbank, um bestimmte Benutzer -Token abzurufen, die auf die API zugreifen. Das Token wird an die OAuth -Klasse übergeben, die das Feed mit dem bereitgestellten Token abholt und an die SocialFeeds -Klasse zurückgibt.

<?php
class A
{
    public function a1() {
        $b = new B();
        $b->b1();
    }
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
<?php
class SocialFeeds
{
    public function getSocialFeeds() {
        $twService = new TwitterService();
        echo $twService->getTweets();
    }
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
<?php
class TwitterService
{
    public function getTweets() {
        $db = new DB();
        $query = "Query to get user token from database";
        $token = $db->getQueryResults($query);

        $oauth = new OAuth();
        return $oauth->requestTwitterFeed($token);
    }
}
Nach dem Login kopieren
<?php
class OAuth
{
    public function requestTwitterFeed($token) {
        // Retrieve and return twitter feed using the token         
    }
}
Nach dem Login kopieren

Es ist offensichtlich, dass SocialFeeds auf Twitterservice angewiesen sind. Aber TwitterService hängt von DB und OAuth ab, sodass SocialFeeds indirekt von DB und OAuth abhängen. Was ist das Problem? SocialFeeds beruhen auf der konkreten Implementierung von drei Klassen. Daher ist es unmöglich, SocialFeeds ohne die tatsächliche Umsetzung anderer Klassen getrennt zu testen. Oder nehmen wir an, wir möchten eine andere Datenbank oder einen anderen OAuth -Anbieter verwenden. In diesem Fall müssen wir die vorhandene Klasse durch die neue Klasse im gesamten Code ersetzen.

Fix spezifische Abhängigkeiten

Die Lösung für diese Abhängigkeiten ist einfach, d. H. Dynamisch Objekte bereitzustellen, wenn dies erforderlich ist, ohne konkrete Implementierungen zu verwenden. Es gibt zwei Arten von Techniken, die Abhängigkeiten injizieren können: Konstruktor-basierte Abhängigkeitsinjektion und setterbasierte Injektion.

Konstruktorbasierte Injektion

Mit Konstruktor-basierter Abhängigkeitsinjektion wird das Abhängigkeitsobjekt extern erstellt und als Parameter an den Konstruktor der Klasse übergeben. Wir können diese Objekte Klassenvariablen zuweisen und sie überall innerhalb der Klasse verwenden. Die Konstruktor-basierte Injektion der SocialFeeds-Klasse lautet wie folgt:

<?php
class DB
{
    public function getQueryResults($query) {
        // Get results from database and return token
    }
}
Nach dem Login kopieren

Eine Instanz von Twitterservice wird als Objekt an den Konstruktor übergeben. SocialFeeds stützen sich immer noch auf Twitterservice, aber jetzt können wir verschiedene Versionen von Twitter -Dienstanbietern und sogar Scheinobjekten für Testzwecke bereitstellen. In Bezug auf TwitterService werden auch DB- und OAuth -Klassen auf ähnliche Weise definiert.

<?php
class SocialFeeds
{
    public $twService;

    public function __construct($twService) {
        $this->twService = $twService;
    }

    public function getSocialFeeds() {
        echo $this->twService->getTweets();
    }
}
Nach dem Login kopieren

setzwerkbasierte Injektion

Verwenden von Setter-basierten Injektionen werden Objekte mit Setter-Methoden anstelle von Konstruktoren bereitgestellt. Das Folgende ist die setzerbasierte Abhängigkeitsinjektionsinjektion der SocialFeeds-Klasse:

<?php
$db = new DB();
$oauth = new OAuth();
$twService = new TwitterService($db, $oauth);
$socialFeeds = new SocialFeeds($twService);
$socialFeeds->getSocialFeeds();
Nach dem Login kopieren

Der Initialisierungscode enthält jetzt DB und OAuth wie folgt:

<?php
class SocialFeeds
{
    public $twService;

    public function getSocialFeeds() {
        echo $this->twService->getTweets();
    }

    public function setTwitterService($twService) {
        $this->twService = $twService;
    }
}
Nach dem Login kopieren

Konstruktor und Setterinjektion

Konstruktor-basierte Injektion oder Setter-basierte Injektion liegt bei Ihnen. Konstruktorbasiertes Injektion ist geeignet, wenn alle Abhängigkeiten eine Klasse instanziieren müssen. Setterbasierte Injektion ist geeignet, wenn nicht jedes Mal Abhängigkeiten erforderlich sind.

pros

  • Konstruktor - Schauen Sie sich nur den Konstruktor der Klasse an, um alle Abhängigkeiten der Klasse zu identifizieren
  • setor - Das Hinzufügen neuer Abhängigkeiten ist so einfach wie das Hinzufügen einer neuen Setter -Methode und baut den vorhandenen Code nicht auf

Nachteile

  • Konstruktor - Hinzufügen neuer Abhängigkeiten wird dem Konstruktor Parameter hinzufügen.
  • setor - Wir müssen manuell nach notwendigen Abhängigkeiten suchen, da sie nirgendwo angegeben sind
Nach dem Verständnis der Abhängigkeitsinjektion und verschiedenen Injektionstechniken ist es Zeit, Pickel zu sehen und wie sie in sie passt.

Pimple's Rolle in di

Wenn wir bereits Abhängigkeiten mit den oben genannten Techniken injizieren können, fragen Sie sich möglicherweise, warum Sie Pickel benötigen. Um diese Frage zu beantworten, müssen wir uns das trockene Prinzip ansehen.

Wiederholen Sie sich nicht (trocken) ist ein Prinzip in der Softwareentwicklung, das darauf abzielt, die Duplikation verschiedener Informationen zu verringern, was besonders bei mehrschichtigen Architekturen nützlich ist. Die Aussage des Trockenprinzips lautet: "Jedes Wissenfragment muss eine einzige, klare, maßgebliche Darstellung in einem System haben" - Wikipedia

Betrachten Sie das Konstruktor-basierte Injektionsbeispiel. Jedes Mal, wenn wir ein Objekt der SocialFeed -Klasse wollen, müssen wir den gesamten Setup -Prozess der Instanziierung und Übergabe seiner Abhängigkeiten wiederholen. Laut Trocken sollten ein solcher Code vermieden werden, um Wartungsprobleme zu vermeiden. Pimple fungiert als Container, der solche Abhängigkeiten definiert, um eine Duplikation zu vermeiden. Schauen wir uns ein einfaches Beispiel an, um zu sehen, wie Pickel funktioniert.

<?php
class A
{
    public function a1() {
        $b = new B();
        $b->b1();
    }
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Erstellen Sie eine Instanz von Pickel als Behälter zum Speichern von Abhängigkeiten. Es implementiert die SPL -ArrayAccess -Schnittstelle, so dass die Verwendung von Arrays sehr ähnlich ist. Erstens definieren wir einen Schlüssel, der den Namen einer gewünschten Klasse enthält. Wir definieren dann eine Schließung, um eine Instanz der angegebenen Klasse zurückzugeben, die als Dienstleistung fungiert. Beachten Sie, dass eine Instanz des Containers an $ C übergeben wird, sodass wir nach Bedarf auf andere definierte Schlüssel verweisen können. Wenn wir nun eine Instanz einer Klasse wollen, können wir uns auf den Schlüssel verweisen, um das Objekt abzurufen. Konvertieren wir das Beispiel für SocialFeeds in Pickel. Die Beispiele auf der offiziellen Pickle-Website zeigen Konstruktor-basierte Injektion, sodass wir hier die setterbasierte Injektion veranschaulichen werden. Denken Sie daran, dass wir, um Pickle zu verwenden, keine zuvor definierten Settermethoden oder Code ändern müssen - wir sind nur die Logik zusammengefasst.

<?php
class SocialFeeds
{
    public function getSocialFeeds() {
        $twService = new TwitterService();
        echo $twService->getTweets();
    }
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
dB- und OAuth -Klassen sind beide unabhängige Module, daher geben wir ihre neuen Instanzen direkt in die Schließung zurück. Anschließend verwenden wir die setzterbasierte Injektion, um der TwitterService-Klasse Abhängigkeiten hinzuzufügen. Wir haben den DB- und OAuth -Klassen dem Container hinzugefügt, damit wir mit $ C ['DB'] und $ c ['oAuth'] direkt in der Funktion zugreifen können. Jetzt werden die Abhängigkeiten im Container als Dienst eingekapselt. Wann immer wir eine andere DB -Klasse oder einen anderen OAuth -Dienst verwenden möchten, ersetzen wir die Klasse nur in der Containeranweisung und alles wird perfekt laufen. Mit Pimple müssen Sie nur neue Abhängigkeiten an einem Ort hinzufügen.

Erweiterte Pickel Verwendung

In dem obigen Szenario gibt Pimple jedes Mal, wenn sie angefordert wird, eine neue Instanz jeder Klasse aus der Schließung zurück. In einigen Fällen müssen wir dasselbe Objekt jedes Mal eine neue Instanz verwenden, z. B. eine Verbindung zu einer Datenbank ist ein perfektes Beispiel. Pimple bietet die Möglichkeit, dieselbe Instanz mit einem gemeinsam genutzten Objekt zurückzugeben.

<?php
class A
{
    public function a1() {
        $b = new B();
        $b->b1();
    }
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Außerdem haben wir bisher alle Abhängigkeiten an einem einzigen Ort im Pickelbehälter definiert. Betrachten Sie jedoch einen Fall, in dem wir einen Dienst benötigen, der seine Abhängigkeiten hat, aber etwas unterschiedlich als der ursprüngliche Service konfiguriert ist. Angenommen, wir müssen auf das ORM zugreifen, um eine Funktionalität der Twitterservice -Klasse zu implementieren. Wir können die vorhandene Schließung nicht ändern, da alle vorhandenen Funktionen zur Verwendung von ORM gezwungen werden. Pimple bietet die Extend () -Methode zur dynamischen Änderung vorhandener Schließungen, ohne die ursprüngliche Implementierung zu beeinflussen. Betrachten Sie den folgenden Code:

<?php
class SocialFeeds
{
    public function getSocialFeeds() {
        $twService = new TwitterService();
        echo $twService->getTweets();
    }
}
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Jetzt können wir in speziellen Fällen verschiedene Erweiterungsversionen von Tweet_Service verwenden. Der erste Parameter ist der Name des Dienstes, und der zweite Parameter ist eine Funktion, die auf Objektinstanzen und Container zugreifen kann. Tatsächlich ist Extend () eine leistungsstarke Möglichkeit, Abhängigkeiten in unterschiedliche Situationen dynamisch hinzuzufügen. Stellen Sie jedoch sicher, dass die erweiterte Version des Dienstes auf ein Minimum einschränkt, da er die Menge des doppelten Codes erhöht.

Zusammenfassung

Verwalten von Abhängigkeiten ist eine der wichtigsten und schwierigsten Aufgaben bei der Entwicklung von Webanwendungen. Wir können die Abhängigkeitsinjektion von Konstruktoren und Setter -Methoden verwenden, um sie effektiv zu verwalten. Die Abhängigkeitsinjektion selbst hat jedoch auch einige Probleme, und Pimple löst diese Probleme, indem sie einen leichten Behälter bereitstellen, um Objektabhängigkeiten auf trockene Weise zu erstellen und zu speichern. Teilen Sie Ihre Erfahrungen mit der Verwaltung von Abhängigkeiten in Ihrem Projekt und Ihren Gedanken zum Pickel als Abhängigkeitsinjektionsbehälter in den Kommentaren unten mit.

FAQs über die Abhängigkeitsinjektion mit Pickel (FAQ)

Was ist Pickel und warum wird es in PHP verwendet?

Pimple ist ein einfacher PHP -Abhängigkeitsinjektionsbehälter, mit dem Sie Dienste in Ihrer Anwendung verwalten und zentralisieren können. Es wird in PHP verwendet, wodurch der Code flexibler, wiederverwendbarer und einfacher zu testen ist. Durch die Verwendung von Pimple können Sie Objekte an einem Ort instanziieren und in verschiedene Teile Ihrer Anwendung injizieren, wodurch die Notwendigkeit des globalen Zustands reduziert und Ihr Code leichter zu warten und zu testen ist.

Wie funktioniert Pickel?

Pimple arbeitet durch Speichern von Servicedefinitionen in Containern. Diese Definitionen sind abrufbar (Funktion oder Methode) und geben Instanzen des Dienstes zurück. Wenn Sie von einem Container aus auf einen Dienst zugreifen, führt Pimple die Dienstdefinition aus, um ein Dienstobjekt zu erstellen. Auf diese Weise können Sie Dienste zentralisiert und Dienste während der gesamten Anwendung teilen.

Wie installiere ich Pickel?

Pickel kann mit Composer (PHP -Abhängigkeitsmanagement -Tool) installiert werden. Sie können Composer weltweit auf Ihrem System installieren und dann Pickle in Ihr Projekt einführen, indem Sie den Befehl

ausführen. composer require pimple/pimple

Wie kann man einen Dienst in Pickel definieren?

In Pimple können Sie einen Dienst definieren, indem Sie einem Schlüssel in einem Container ein Callable -Objekt zuweisen. Das Callable -Objekt sollte eine Instanz des Dienstes zurückgeben. Zum Beispiel können Sie einen Dienst für die Mail -Absenderklasse wie folgt definieren:

$container['mailer'] = function ($c) { return new Mailer($c['smtp']); };

In diesem Beispiel wird der E -Mail -Sender -Dienst als neue Instanz der Mailerklasse definiert, in der der SMTP -Dienst als Abhängigkeit injiziert wird.

Wie kann man in Pickle zugänglich machen?

Sie können mit Array -Notation mit Servicetasten in Pickle in Pickle zugreifen. Sie können beispielsweise auf den E -Mail -Absenderdienst wie folgt zugreifen: $mailer = $container['mailer'];. Wenn Sie auf einen Dienst zugreifen, führt Pimple die Servicedefinition aus und gibt das Dienstobjekt zurück.

Wie kann ich Dienste in Pickple teilen?

standardmäßig gibt Pimple jedes Mal, wenn er auf den Dienst zugreift, eine neue Instanz des Dienstes zurück. Wenn Sie den Dienst teilen und jedes Mal dieselbe Instanz zurückgeben möchten, können Sie die share() -Methode verwenden. Sie können beispielsweise den Mail -Absender -Dienst wie folgt freigeben: $container['mailer'] = $container->share(function ($c) { return new Mailer($c['smtp']); });.

Kann ich den Service in Pickel verlängern?

Ja, Sie können die Methode extend() verwenden, um Dienste in Pickel zu erweitern. Auf diese Weise können Sie den Dienst nach der Definition ändern. Sie können beispielsweise den E -Mail -Absenderdienst wie diesen erweitern, um zusätzliche Konfiguration hinzuzufügen:

$container['mailer'] = $container->extend('mailer', function ($mailer, $c) { $mailer->setFrom($c['email.from']); return $mailer; });

In diesem Beispiel wird die setFrom() -Methode auf den E -Mail -Absenderdienst mit dem email.from -Dienst als Parameter aufgerufen.

Wie schützt ich Parameter in Pickel?

In Pimple können Sie die Methode protect() verwenden, um Parameter zu schützen (die nicht als Diensteparameter angesehen werden sollten). Auf diese Weise können Sie Werte in einem Container speichern, ohne sie als Servicedefinitionen zu behandeln. Sie können beispielsweise den Konfigurationswert wie folgt schützen: $container['config.value'] = $container->protect(function () { return 'value'; });.

Wie kann man Pickple in einem Projekt verwenden?

Sie können Pimple in einem Projekt verwenden, indem Sie eine neue Instanz der Pimpecontainer -Klasse erstellen und dort einen Dienst definieren. Sie können dann vom Container auf den Dienst zugreifen, wo Sie ihn in der Anwendung benötigen. Auf diese Weise können Sie Dienste zentralisiert verwalten und in verschiedene Teile Ihrer Anwendung injizieren.

Was sind die Vorteile der Verwendung von Pickel?

Pimple bietet viele Vorteile für die PHP -Entwicklung. Dies macht Ihren Code flexibler, da Sie Dienste auf zentralisierte Weise verwalten können. Dies erleichtert Ihr Code, da Sie die Wiederverwendung erleichtern können, da Sie Dienste während Ihrer Bewerbung freigeben können. Dadurch wird Ihr Code leichter zu testen, da Sie Mockdienste zum Testen einfügen können. Durch die Verwendung von Pickle können Sie die Qualität Ihres Codes verbessern und die Wartung und Prüfung erleichtern.

Das obige ist der detaillierte Inhalt vonPHP Master | Abhängigkeitsinjektion mit Pickel. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage