Heim  >  Artikel  >  PHP-Framework  >  Holen Sie sich die Containerinstanz im Code (Laravel)

Holen Sie sich die Containerinstanz im Code (Laravel)

藏色散人
藏色散人nach vorne
2021-08-06 09:35:101843Durchsuche

Dieser Artikel wurde von laravelTutorial-Kolumne geschrieben, um vorzustellen, wie man die Containerinstanz in den Code einfügt. Ich hoffe, dass er Freunden, die sie benötigen, hilfreich sein wird!

Die Laravel-Container-Instanz ist während des gesamten Anforderungslebenszyklus einzigartig und verwaltet alle Dienstkomponenteninstanzen. Welche Möglichkeiten gibt es also, eine Instanz des Laravel-Containers zu erhalten? Die folgenden Methoden werden häufig verwendet:

1) Über die Hilfefunktion der App:

$app = app();

Die Hilfsfunktion der App ist in der Datei

Holen Sie sich die Containerinstanz im Code (Laravel)

definiert. Diese Datei definiert viele Hilfefunktionen und wird automatisch in die geladen Datei über Composer-Projekt. Daher kann auf die Funktionen von jeder Codestelle aus zugegriffen werden, die an der HTTP-Anforderungsverarbeitung beteiligt ist, z. B. app().

2) Über die App-Fassade

<?php
Route::get(&#39;/&#39;, function () {
    dd(App::basePath());
    return &#39;&#39;;
});

Der Weg, die Container-Instanz über die App-Fassade zu erhalten, unterscheidet sich von der oben beschriebenen. Sie können die App nicht zuerst einer Variablen zuweisen und dann die Container-Methode über die Variable aufrufen. Dies liegt daran, dass App nur ein Klassenname ist und wir einen Klassennamen nicht in eine Variable kopieren können. $app = App; ist keine zulässige ausführbare Anweisung, aber $app = app(); ist eine zulässige ausführbare Anweisung, da danach app() steht, was auf einen Funktionsaufruf hinweist. App::basePath(); ist ebenfalls eine zulässige Anweisung, sie ruft die statische Methode der Klasse auf.

Fügen Sie zwei weitere Punkte hinzu:

Erster Punkt: Facade ist eine besondere Funktion im Laravel-Framework. Jede Facade wird einem Instanzobjekt im Container zugeordnet. Wir können es direkt über den statischen Methodenaufruf der Facade-Klasse aufrufen. Methoden des Instanzobjekts, dem es zugeordnet ist. Wenn beispielsweise die Fassade von App App::basePath() aufruft, entspricht sie tatsächlich app()->basePath().

Dieser zugrunde liegende Mechanismus basiert auch auf den Eigenschaften der PHP-Sprache. Er muss in jeder Facade ein statisches Mitglied festlegen und es einem Instanzobjekt des Dienstes zuordnen Analysieren Sie den Methodennamen, rufen Sie dann die gleichnamige Methode der zugehörigen Dienstinstanz auf und geben Sie schließlich das Ergebnis zurück.

Ich denke, es reicht aus, zu verstehen, welche Rolle Facade spielen kann. Um die Implementierungsdetails zu verstehen, hat es in der tatsächlichen Entwicklung keinen Einfluss auf die Verwendung von Laravel Rahmen überhaupt. Darüber hinaus ist es beim tatsächlichen Codieren sehr einfach, eine Facade anzupassen. Erben Sie einfach die von Laravel gekapselte Facade-Basisklasse:

<?php
namespace ThirdProviders\CasServer\Facades;
use Illuminate\Support\Facades\Facade;
use ThirdProviders\CasServer\CasServerManager;
class CasServer extends Facade
{
    protected static function getFacadeAccessor()
    {
        return CasServerManager::class;
    }
}

Implementieren Sie die getFacadeAccessor-Methode der Facade-Basisklasse, und das Laravel-Framework weiß, welche Serviceinstanz diese Facade hat Klasse sollte mit „Steh auf“ verbunden sein. Tatsächlich ist der von dieser getFacadeAccess-Methode zurückgegebene Name der Dienstbindungsname, der später eingeführt wird. Im Laravel-Container hat eine Dienstinstanz einen festen Bindungsnamen und die Instanz kann über diesen Namen gefunden werden. Warum muss die Facade-Klasse also nur den Namen der Dienstbindung zurückgeben?

Wir können uns den Code der App Facade-Klasse ansehen:

<?php
namespace Illuminate\Support\Facades;
/**
 * @see \Illuminate\Foundation\Application
 */
class App extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return &#39;app&#39;;
    }
}

Sein getFacadeAccessor gibt eine Zeichenfolge „app“ zurück. Dies ist der Name, den der Laravel-Container verwendet, um sich selbst zu binden.

Zweiter Punkt: Aus dem Quellcode der App Facade im vorherigen Punkt können wir ersehen, dass der vollständige Klassenname der App Facade tatsächlich lautet: IlluminateSupportFacadesApp. Warum können wir also direkt über den Kurznamen App in der darauf zugreifen? Code? :

<?php
Route::get(&#39;/&#39;, function () {
    dd(App::basePath());
    return &#39;&#39;;
});

Sie sehen, dass der obige Code keine Verwendung oder vollständig qualifizierte Methode zur Verwendung von IlluminateSupportFacadesApp verwendet. Tatsächlich ist App völlig gleichwertig mit IlluminateSupportFacadesApp, außer dass App viel kürzer als IlluminateSupportFacadesApp ist und keine Verwendung erfordert, sodass die Verwendung bequem ist. Dies hängt mit den im Laravel-Container konfigurierten Aliasen zusammen. In config/app.php gibt es einen Abschnitt mit Aliasen, der der Konfiguration einiger Arten von Aliasen gewidmet ist:

&#39;aliases&#39; => [
    &#39;App&#39; => Illuminate\Support\Facades\App::class,
    &#39;Artisan&#39; => Illuminate\Support\Facades\Artisan::class,
    &#39;Auth&#39; => Illuminate\Support\Facades\Auth::class,
    &#39;Blade&#39; => Illuminate\Support\Facades\Blade::class,
    &#39;Bus&#39; => Illuminate\Support\Facades\Bus::class,
    &#39;Cache&#39; => Illuminate\Support\Facades\Cache::class,
    &#39;Config&#39; => Illuminate\Support\Facades\Config::class,
    &#39;Cookie&#39; => Illuminate\Support\Facades\Cookie::class,
    &#39;Crypt&#39; => Illuminate\Support\Facades\Crypt::class,
    &#39;DB&#39; => Illuminate\Support\Facades\DB::class,
    &#39;Eloquent&#39; => Illuminate\Database\Eloquent\Model::class,
    &#39;Event&#39; => Illuminate\Support\Facades\Event::class,
    &#39;File&#39; => Illuminate\Support\Facades\File::class,
    &#39;Gate&#39; => Illuminate\Support\Facades\Gate::class,
    &#39;Hash&#39; => Illuminate\Support\Facades\Hash::class,
    &#39;Lang&#39; => Illuminate\Support\Facades\Lang::class,
    &#39;Log&#39; => Illuminate\Support\Facades\Log::class,
    &#39;Mail&#39; => Illuminate\Support\Facades\Mail::class,
    &#39;Notification&#39; => Illuminate\Support\Facades\Notification::class,
    &#39;Password&#39; => Illuminate\Support\Facades\Password::class,
    &#39;Queue&#39; => Illuminate\Support\Facades\Queue::class,
    &#39;Redirect&#39; => Illuminate\Support\Facades\Redirect::class,
    &#39;Redis&#39; => Illuminate\Support\Facades\Redis::class,
    &#39;Request&#39; => Illuminate\Support\Facades\Request::class,
    &#39;Response&#39; => Illuminate\Support\Facades\Response::class,
    &#39;Route&#39; => Illuminate\Support\Facades\Route::class,
    &#39;Schema&#39; => Illuminate\Support\Facades\Schema::class,
    &#39;Session&#39; => Illuminate\Support\Facades\Session::class,
    &#39;Storage&#39; => Illuminate\Support\Facades\Storage::class,
    &#39;URL&#39; => Illuminate\Support\Facades\URL::class,
    &#39;Validator&#39; => Illuminate\Support\Facades\Validator::class,
    &#39;View&#39; => Illuminate\Support\Facades\View::class
],

Dann wird während des Anforderungsverarbeitungsprozesses des Laravel-Frameworks die Klasse IlluminateFoundationBootstrapRegisterFacades verwendet wird verwendet. Registrieren wir diese Aliase in der globalen Umgebung:

<?php
namespace Illuminate\Foundation\Bootstrap;
use Illuminate\Support\Facades\Facade;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Contracts\Foundation\Application;
class RegisterFacades
{
    /**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function bootstrap(Application $app)
    {
        Facade::clearResolvedInstances();
        Facade::setFacadeApplication($app);
        AliasLoader::getInstance($app->make(&#39;config&#39;)->get(&#39;app.aliases&#39;, []))->register();
    }
}

Damit wir Aliase anstelle des vollständigen Typnamens direkt verwenden können, um dieselbe Zugriffsfunktion auszuführen. Wenn Sie selbst einige Klassen mit langen Namen geschrieben haben und diese häufig im Code verwendet werden, können Sie sie auch im Alias ​​config/app.php konfigurieren, und Laravel registriert sie für uns.

3) Eine andere Möglichkeit, die Laravel-Container-Instanz zu erhalten, besteht darin, $this->app direkt im Dienstanbieter zu verwenden.

Der Dienstanbieter wird später eingeführt, aber er wird erst jetzt eingeführt. Da Dienstanbieterklassen vom Laravel-Container instanziiert werden, erben diese Klassen von IlluminateSupportServiceProvider, das ein Instanzattribut $app definiert. Wenn Laravel den Dienstanbieter instanziiert, wird die Laravel-Containerinstanz injiziert. Gehen Sie zu dieser $app. Beim Dienstanbieter können wir also jederzeit über $this->$app auf die Laravel-Container-Instanz zugreifen, ohne die Funktion app() oder App Facade zu verwenden.

Weitere technische Artikel zu Laravel finden Sie in der Kolumne Laravel-Tutorial!

Das obige ist der detaillierte Inhalt vonHolen Sie sich die Containerinstanz im Code (Laravel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:杨子. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen