Cet article présente principalement l'interprétation de base des façades dans Laravel, qui a une certaine valeur de référence. Maintenant, je le partage avec tout le monde. Les amis dans le besoin peuvent s'y référer
. Les façades sont un composant que nous utilisons très fréquemment dans le développement d'applications Laravel et qui n'est pas appelé de manière appropriée un composant. En fait, il s'agit d'un ensemble d'interfaces de classe statique ou de proxys qui permettent aux développeurs d'accéder simplement à divers services liés au conteneur de services. Les façades sont expliquées dans la documentation Laravel comme suit :
Les façades fournissent une interface "statique" pour les classes disponibles dans le conteneur de services de l'application. Laravel est livré avec de nombreuses façades, et vous les utilisez peut-être sans même le savoir ! En tant que « proxy statique » pour les classes de base dans le conteneur de services, les « façades » Laravel présentent les avantages d'une syntaxe concise et facile à exprimer, tout en conservant une testabilité et une flexibilité plus élevées que les méthodes statiques traditionnelles.
La route que nous utilisons souvent est une façade, qui est un alias de la classe IlluminateSupportFacadesRoute
. Cette classe Facade représente le service router
enregistré dans le conteneur de services, donc via la classe Route, nous pouvons facilement l'utiliser. divers services fournis dans le service du routeur, et la résolution du service impliquée est complètement implicitement complétée par Laravel, ce qui rend le code d'application beaucoup plus simple dans une certaine mesure. Ci-dessous, nous examinerons brièvement le processus entre l'enregistrement des façades dans le framework Laravel et leur utilisation par l'application. Facades travaille en étroite collaboration avec ServiceProvider, donc si vous comprenez ces processus, il sera utile de développer des composants Laravel personnalisés.
En parlant d'enregistrement des façades, nous devons revenir à l'étape Bootstrap qui a été mentionnée à plusieurs reprises lors de l'introduction d'autres composants de base. Il y a un démarrage avant que la requête ne passe par le middleware et. routage. Processus de candidature :
//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()); } }
Pendant le processus de démarrage de l'application IlluminateFoundationBootstrapRegisterFacades
A cette étape, les Façades utilisées dans l'application seront enregistrées.
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(); } }
Ici, les alias seront enregistrés pour toutes les façades via les instances de la classe AliasLoader
. La correspondance entre les façades et les alias est stockée dans le tableau config/app.php
du fichier $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, ...... ]
Regardez comment ces alias sont enregistrés dans AliasLoader
// 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); }
Grâce à l'extrait de code ci-dessus, vous pouvez voir qu'AliasLoader enregistre la méthode de chargement en tête de la file d'attente des fonctions SPL __autoload. Jetez un œil au code source de la méthode de chargement :
public function load($alias) { if (isset($this->aliases[$alias])) { return class_alias($this->aliases[$alias], $alias); } }
Dans la méthode de chargement, la classe Facade dans la configuration $aliases
crée un alias correspondant. Par exemple, lorsque nous utilisons la classe alias <. 🎜>, PHP se chargera via AliasLoader. La méthode consiste à créer une classe d'alias Route
à partir de la classe IlluminateSupportFacadesRoute::class
, donc lorsque nous utilisons l'alias Route
dans le programme, nous utilisons en fait la classe Route
. `IlluminateSupportFacadesRoute
lors de l'enregistrement d'itinéraires, puis Route::get('/uri', 'Controller@action);
Comment. vers le service de routage par proxy ? Cela implique la résolution implicite du service dans la Façade. Jetons un coup d'œil au code source de la classe Route : Route
class Route extends Facade { /** * Get the registered name of the component. * * @return string */ protected static function getFacadeAccessor() { return 'router'; } }
, get
, post
et les autres méthodes de routage ne sont pas dans la classe parent, mais nous savons que l'appel d'une méthode statique qui n'existe pas dans la classe déclenchera la delete
méthode statique__callStatic
de PHP
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]; }
lors de l'étape registerBaseServiceProviders lors de l'initialisation de l'application (voir la construction. méthode d'application pour plus de détails) La classe correspondant au service de routeur enregistré dans le conteneur de service : IlluminateRoutingRoutingServiceProvider
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); }); } ...... }
, donc la Route Facade proxy en fait cette classe, et Route::get appelle en fait le Objet IlluminateRoutingRouter
Deux points supplémentaires pour la méthode get IlluminateRoutingRouter
/** * 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); }
utilisé lors de l'analyse du service est défini dans le , dont la référence est le conteneur de service. static::$app
RegisterFacades
Ce qui précède représente l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'étude de chacun. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois !
Recommandations associées :
Interprétation du middleware Laravel (Middleware)
Interprétation du routage Laravel (Route)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!