Heim  >  Artikel  >  Backend-Entwicklung  >  Laravel Core Interpretation Fassaden

Laravel Core Interpretation Fassaden

不言
不言Original
2018-07-06 14:45:451480Durchsuche

Dieser Artikel stellt hauptsächlich die Kerninterpretation von Fassaden in Laravel vor, die einen gewissen Referenzwert hat. Jetzt kann ich sie mit allen Freunden in Not teilen.

Was sind Fassaden?

Fassaden sind eine Komponente, die wir bei der Entwicklung von Laravel-Anwendungen sehr häufig verwenden. Sie werden nicht ordnungsgemäß als Komponente bezeichnet. Tatsächlich handelt es sich um eine Reihe statischer Klassenschnittstellen oder Proxys, die es Entwicklern ermöglichen, einfach auf verschiedene an den Service-Container gebundene Dienste zuzugreifen. Die Erklärung von Facades in der Laravel-Dokumentation lautet wie folgt:

Facades stellen eine „statische“ Schnittstelle für Klassen bereit, die im Servicecontainer der Anwendung verfügbar sind. Laravel verfügt über viele Fassaden, und Sie verwenden sie möglicherweise, ohne es zu wissen! Als „statischer Proxy“ für Basisklassen im Service-Container bieten Laravel-„Fassaden“ die Vorteile einer prägnanten und einfach auszudrückenden Syntax und bieten gleichzeitig eine höhere Testbarkeit und Flexibilität als herkömmliche statische Methoden.

Die Route, die wir häufig verwenden, ist eine Fassade, ein Alias ​​der IlluminateSupportFacadesRoute-Klasse. Diese Fassadenklasse stellt einen Proxy für den im Servicecontainer registrierten router-Dienst dar, sodass wir ihn bequem über die Route-Klasse verwenden können Verschiedene im Router-Dienst bereitgestellte Dienste und die damit verbundene Dienstauflösung werden vollständig implizit von Laravel abgeschlossen, was den Anwendungscode bis zu einem gewissen Grad erheblich vereinfacht. Im Folgenden werfen wir einen kurzen Blick auf den Prozess zwischen der Registrierung von Facades im Laravel-Framework und der Verwendung durch die Anwendung. Facades arbeitet eng mit ServiceProvider zusammen. Wenn Sie diese Prozesse verstehen, ist es hilfreich, benutzerdefinierte Laravel-Komponenten zu entwickeln.

Fassaden registrieren

Apropos Fassadenregistrierung: Wir müssen zur Bootstrap-Phase zurückkehren, die bei der Einführung anderer Kernkomponenten oft erwähnt wurde. Es gibt einen Start, bevor die Anforderung die Middleware durchläuft Routing. Bewerbungsprozess:

//Class: \Illuminate\Foundation\Http\Kernel
 
protected function sendRequestThroughRouter($request)
{
    $this->app->instance('request', $request);

    Facade::clearResolvedInstance('request');

    $this->bootstrap();

    return (new Pipeline($this->app))
                    ->send($request)
                    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                    ->then($this->dispatchToRouter());
}

//引导启动Laravel应用程序
public function bootstrap()
{
    if (! $this->app->hasBeenBootstrapped()) {
        /**依次执行$bootstrappers中每一个bootstrapper的bootstrap()函数
         $bootstrappers = [
               'Illuminate\Foundation\Bootstrap\DetectEnvironment',
             'Illuminate\Foundation\Bootstrap\LoadConfiguration',
              'Illuminate\Foundation\Bootstrap\ConfigureLogging',
             'Illuminate\Foundation\Bootstrap\HandleExceptions',
             'Illuminate\Foundation\Bootstrap\RegisterFacades',
             'Illuminate\Foundation\Bootstrap\RegisterProviders',
             'Illuminate\Foundation\Bootstrap\BootProviders',
            ];*/
            $this->app->bootstrapWith($this->bootstrappers());
    }
}

Beim Starten der Bewerbung IlluminateFoundationBootstrapRegisterFacades In dieser Phase werden die in der Bewerbung verwendeten Fassaden registriert.

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(array_merge(
            $app->make('config')->get('app.aliases', []),
            $app->make(PackageManifest::class)->aliases()
        ))->register();
    }
}

Hier werden Aliase für alle Facades über Instanzen der AliasLoader-Klasse registriert. Die Korrespondenz zwischen Facades und Aliasen wird im config/app.php-Array der $aliases

'aliases' => [

    'App' => Illuminate\Support\Facades\App::class,
    'Artisan' => Illuminate\Support\Facades\Artisan::class,
    'Auth' => Illuminate\Support\Facades\Auth::class,
    ......
    'Route' => Illuminate\Support\Facades\Route::class,
    ......
]
gespeichert

Siehe Sehen wir uns an, wie diese Aliase in AliasLoader registriert werden

// class: Illuminate\Foundation\AliasLoader
public static function getInstance(array $aliases = [])
{
    if (is_null(static::$instance)) {
        return static::$instance = new static($aliases);
    }

    $aliases = array_merge(static::$instance->getAliases(), $aliases);

    static::$instance->setAliases($aliases);

    return static::$instance;
}

public function register()
{
    if (! $this->registered) {
        $this->prependToLoaderStack();

        $this->registered = true;
    }
}

protected function prependToLoaderStack()
{
    // 把AliasLoader::load()放入自动加载函数队列中,并置于队列头部
    spl_autoload_register([$this, 'load'], true, true);
}

Aus dem obigen Codeausschnitt können Sie sehen, dass AliasLoader die Lademethode an der Spitze der SPL-Funktionswarteschlange __autoload registriert. Schauen Sie sich den Quellcode der Load-Methode an:

public function load($alias)
{
    if (isset($this->aliases[$alias])) {
        return class_alias($this->aliases[$alias], $alias);
    }
}

In der Load-Methode erstellt die Facade-Klasse in der

-Konfiguration einen entsprechenden Alias, wenn wir beispielsweise die Alias-Klasse $aliases verwenden , PHP verwendet die Load-Methode von AliasLoader. Erstellen Sie eine Alias-Klasse Route für die Klasse IlluminateSupportFacadesRoute::class. Wenn wir also den Alias ​​Route im Programm verwenden, verwenden wir tatsächlich die Klasse Route. `IlluminateSupportFacadesRoute

Fassaden-Proxy-Dienst auflösen

Nachdem wir Fassaden im Framework registriert haben, können wir die Fassade in der Anwendung verwenden. Beispielsweise verwenden wir bei der Registrierung von Routen häufig

Wie Um einen Proxy für den Routing-Dienst zu erstellen, müssen wir uns den Quellcode der Route-Klasse ansehen: Route::get('/uri', 'Controller@action);

class Route extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'router';
    }
}
RouteEs gibt nur eine einfache Methode, aber keine

,

, get und andere Routing-Methoden sind nicht in der übergeordneten Klasse, aber wir wissen, dass der Aufruf einer statischen Methode, die in der Klasse nicht vorhanden ist, die poststatische Methode delete

public static function __callStatic($method, $args)
{
    $instance = static::getFacadeRoot();

    if (! $instance) {
        throw new RuntimeException('A facade root has not been set.');
    }

    return $instance->$method(...$args);
}

//获取Facade根对象
public static function getFacadeRoot()
{
    return static::resolveFacadeInstance(static::getFacadeAccessor());
}

/**
 * 从服务容器里解析出Facade对应的服务
 */
protected static function resolveFacadeInstance($name)
{
    if (is_object($name)) {
        return $name;
    }

    if (isset(static::$resolvedInstance[$name])) {
        return static::$resolvedInstance[$name];
    }

    return static::$resolvedInstance[$name] = static::$app[$name];
}
by in der Unterklasse Der in Route Facade festgelegte Accessor (String-Router) analysiert den entsprechenden Dienst aus dem Service-Container. Der Router-Service wird im Service-Container von __callStatic während der Phase „registerBaseServiceProviders“ registriert, wenn die Anwendung initialisiert wird (siehe Einzelheiten zur Konstruktionsmethode der Anwendung) Innen:

class RoutingServiceProvider extends ServiceProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->registerRouter();
        ......
    }

    /**
     * Register the router instance.
     *
     * @return void
     */
    protected function registerRouter()
    {
        $this->app->singleton('router', function ($app) {
            return new Router($app['events'], $app);
        });
    }
    ......
}

Die dem Router-Dienst entsprechende Klasse ist IlluminateRoutingRoutingServiceProvider, sodass die Route Facade diese Klasse tatsächlich als Proxy fungiert und Route::get tatsächlich die get-Methode von Objekt

/**
 * Register a new GET route with the router.
 *
 * @param  string  $uri
 * @param  \Closure|array|string|null  $action
 * @return \Illuminate\Routing\Route
 */
public function get($uri, $action = null)
{
    return $this->addRoute(['GET', 'HEAD'], $uri, $action);
}

Fügen Sie zwei Punkte hinzu:IlluminateRoutingRouterIlluminateRoutingRouter

Das beim Parsen des Dienstes verwendete

wird im anfänglichen
    festgelegt, das sich auf den Dienstcontainer bezieht .
  1. static::$appRegisterFacadesstatic::$app['router'] Der Grund, warum der Router-Dienst aus dem Service-Container in Form von Array-Zugriff analysiert werden kann, liegt darin, dass der Service-Container ArrayAccess implementiert Es gibt keine SPL-Schnittstelle. Für Konzepte können Sie das offizielle Dokument ArrayAccess

  2. Zusammenfassung

  3. lesen. Wir können sehen, dass Fassade und Dienstanbieter (ServiceProvider) eng zusammenarbeiten. Ja. Wenn Sie also in Zukunft Ihren eigenen benutzerdefinierten Laravel-Dienst schreiben, können Sie zusätzlich zur Registrierung des Dienstes im Service-Container über den ServiceProvider der Komponente auch eine Fassade bereitstellen in der Komponente, damit die Anwendung problemlos auf den von Ihnen geschriebenen benutzerdefinierten Dienst zugreifen kann.

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, er wird für das Studium aller hilfreich sein. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website.

Verwandte Empfehlungen:

Interpretation der Laravel-Middleware (Middleware)

Interpretation des Laravel-Routings (Route)

Das obige ist der detaillierte Inhalt vonLaravel Core Interpretation Fassaden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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