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.
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.
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, ...... ]
// 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); }
public function load($alias) { if (isset($this->aliases[$alias])) { return class_alias($this->aliases[$alias], $alias); } }
-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
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'; } }
Route
Es 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 post
statische 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]; }
__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 < aufruft 🎜> 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:IlluminateRoutingRouter
IlluminateRoutingRouter
Das beim Parsen des Dienstes verwendete
wird im anfänglichenstatic::$app
RegisterFacades
static::$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
Zusammenfassung
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!