This article mainly introduces about Laravel's facade appearance system analysis, has certain reference value, now shares to everybody, has the need friend can refer to
Today we will learn another topic "facade (appearance) in the Laravel core architecture.
This article will start from the following aspects, comprehensively explain the operation principle of facade in Laravel, in order to facilitate understanding of all subsequent facade translated "appearance":
Brief introduction of "appearance" design mode;
laravel"appearance" Loading principle;
laravel"appearance" basic use.
What is the "look" design pattern
Appearance pattern definition
Provides a unified portal for a set of interfaces in a subsystem. The appearance pattern defines a high-level interface that makes this subsystem easier to use.
The
appearance pattern is a very high-frequency structural design pattern that simplifies the interaction between the client and the subsystem by introducing a visual role.
Provides a unified portal for complex subsystem calls, reduces the coupling between the subsystem and the client, and facilitates client invocation. -Design mode Java Edition
The core is the introduction of a "skin" role between the client (consumer) and the subsystem (interface or service) .
It transforms the user and subsystem from direct coupling to the "look" class to provide a unified interface to the user to reduce the coupling between the client and the subsystem.
Structure:
About "appearance mode" can read design mode Java Edition-appearance mode
Laravel Appearance components
The "appearance" component in Laravel is actually the "static proxy" of the underlying class in the service container, which will Laravel the "contracts defined in the kernel (in Laravel and
Called a service, contract, or interface that we normally refer to) "is encapsulated in a static and callable manner in various" look "services for our use.
Appearance loading principle
Before we explain how to use the appearance component, we will still go into the deep analysis of how the "look" component is loaded into the project by Laravel. This step is
Use the "appearance" component as a precondition.
Appearance Component Configuration
The configuration data for all the built-in skin components is defined in the config/app.php file As with Laravel other services. Let's take a look at the configuration data for the aliases node:
... ' Aliases ' + [ ' App ' = Illuminate\support\facades\app::class, ' Artisan ' + illuminate\support\ Facades\artisan::class, ... ], ...
The appearance configuration definition format follows the data format of the alias ":" Skin class . When an HTTP request is received, these "skins" components are loaded into the service during the processing request phase.
The next step is to delve into the loading process of the façade service.
Load Appearance Services
The load work for the "look" service is defined by the \illuminate\foundation\bootstrap\ in the illuminate\foundation\http\kernel kernel Registerfacades::class The startup program is complete.
Boot Boot appearance Service
If you have read one of my other articles in-depth anatomy of the Laravel service provider Implementation principle, you should not be too unfamiliar with the boot program.
The bootloader will process the HTTP request to complete the boot Boot bootstrap (). So here we need to go deep inside the Registerfacades class to learn more about the details of the process.
<?phpnamespace Illuminate\foundation\bootstrap;use Illuminate\foundation\aliasloader;use Illuminate\Support\ Facades\facade;use illuminate\foundation\packagemanifest;use illuminate\contracts\foundation\application;/** * @ Link https://github.com/laravel/framework/blob/56a58e0fa3d845bb992d7c64ac9bb6d0c24b745a/src/Illuminate/ foundation/bootstrap/registerfacades.php */class registerfacades{ /** * Bootstrap the given application. Boot start Service * /Public Function bootstrap (application $app ) {//Clears resolved "appearance" service instance facade:: Clearresolvedinstances (); Inject the Laravel service container into the "appearance" service facade::setfacadeapplication ($app); Load all appearance services aliasloader::getinstance (Array_merge ( $app->make (' config ')->get (' app.aliases ', []), $app->make (packagemanifest::class)->aliases ()) ) ->register (); }}
Loading the façade service has the Aliasloader component complete:
First, all the "look" service configuration aliasesare read from the configuration file config/app.php ;
The alias service is then read from the manifest file $app->make (packagemanifest::class)->aliases ();
The two configuration arrays are combined and injected into the aliasloader complete Registration (register).
Registered appearance Service
Finally, let's see how the aliasloader loader loads all the "look" services into the system.
<?phpnamespace illuminate\foundation;/** * @link https://github.com/laravel/framework/blob/ 56a58e0fa3d845bb992d7c64ac9bb6d0c24b745a/src/illuminate/foundation/aliasloader.php */class AliasLoader{/** * Get o R Create the singleton alias Loader instance. Gets or creates an alias loader singleton instance. */public static function getinstance (array $aliases = []) {if (Is_null (static:: $instance)) {RET Urn static:: $instance = new static ($aliases); } $aliases = Array_merge (static:: $instance->getaliases (), $aliases); Static:: $instance->setaliases ($aliases); return static:: $instance; }/** * Set the registered aliases. Set the alias data to be registered. */Public Function setaliases (array $aliases) {$this->aliases = $aliases; }/** * Register the loader on the Auto-loader stack. Registers the loader with automatic loading. */Public Function Register () {if (! $this->registered) {$this->prependtoloaderstack (); $this->regIstered = true; }}/** * prepend the Load method to the Auto-loader stack. Sets the auto-load method. */protected function Prependtoloaderstack () {//Aliasloader Load method as __autoload implementation Spl_autoloa D_register ([$this, ' Load '], true, true); }/** * Load a class alias if it is registered. Load this "look" service from the registered service. */Public Function load ($alias) {if (static:: $facadeNamespace && strpos ($alias, static:: $facadeNames PACE) = = = 0) {$this->loadfacade ($alias); return true; } if (Isset ($this->aliases[$alias]) {return Class_alias ($this->aliases[$alias], $alias); } }}
Note Here is the knowledge point, in Aliasloader->register () to complete the "external service registration" involves PHP two of knowledge of the application:
➤1. Dynamic introduction of appearance services
We know that the role of the __autoload Magic method is to attempt to load an undefined class, so that when we use a class that is not introduced, it automatically introduces us to this class.
A better solution is to replace the default __autoload () with the spl_autoload_register function, which uses the custom class loader as the __autoload implementation The behavior of a modal function or method.
All Prependtoloaderstack () methods:
/** * prepend The Load method to the Auto-loader stack. Set the automatic loading methods. * /protected function Prependtoloaderstack ( ) {//Aliasloader Load method as __autoload implementation Spl_autoload_register ([$this, ' Load '], true, true); }
is to do this, using the aliasloader->load () method as an automatic loader implementation that dynamically introduces this class when it uses the "look" service.
➤2. Support for appearance service aliases
We have learned that when the "look" service is used, the class is automatically loaded by aliasloader->load () .
At the same time, the Load method completes the alias registration through the Class_alias ($original, $alias) function.
That way, when we use the App class, we're actually using the Illuminate\support\facades\app class.
Perfect, our "dog egg" is at last equated with "the best language in the world". You are me, I am you.
In fact, we have completed the 70%of the work principle of "appearance" service.
Quest Facade
Finally, we will uncover the mystery of facade and study how Laravel realizes facade design patterns.
We took the Illuminatesupportfacadesapp appearance service to unlock the mystery of the use of static methods like App::make () .
In-depth Facadesapp:
<?phpnamespace illuminate\support\facades;class App extends facade{ /** * Get The registered name of the compo nent. * /protected static function Getfacadeaccessor () { return ' app '; }}
We see that its implementation internally only defines a getfacadeaccessor method whose function is to get the name of the registered component of the app;
It seems that we don't get any useful information here. Continue to investigate base class Illuminatesupportfacadesfacade. If you have to go to the laxative browse all the source code.
<?phpnamespace illuminate\support\facades;use mockery;use runtimeexception;use Mockery\MockInterface;/** * @link Https://github.com/laravel/framework/blob/5.6/src/Illuminate/Support/Facades/Facade.php */abstract class facade{ /** * Handle dynamic, static calls to the object. * /public static function __callstatic ($method, $args) { $instance = Static::getfacaderoot (); if (! $instance) { throw new runtimeexception (' A facade root have not been set. '); } return $instance $method (... $args); }}
You will find that the facade base class does not define a method like make, so it is possible to call App::make () statically from the __callstatic start.
But here we need to clarify one more fact: what is the function of "appearance" mode?
It
transforms the user and subsystem from direct coupling to the "look" class to provide a unified interface to the user to reduce the coupling between the client and the subsystem.
The meaning of this sentence is that I do not provide the "appearance", is a layer of service (or component or interface) encapsulation, and then in a unified way to provide you with external calls.
Okay, now let's take a look at how facade::__callstatic gets the actual service and invokes the response method.
First, the actual service instance object is obtained by getfacaderoot static method;
It then invokes the associated method of the instance object and returns the processing result.
<?phpnamespace Illuminate\support\facades;use Mockery;use Runtimeexception;use Mockery\mockinterface;abstract class facade{/** * Get The root object behind the facade. From FA Cade the object that resolves the real service, */public static function Getfacaderoot () {return static::resolvefacadeinstance (static: : Getfacadeaccessor ()); }/** * Resolve The facade root instance from the Container.me resolves real service objects from the Laravel service container */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]; }}
From the functionality of getfacaderoot parsing objects, we can see that it calls the Getfacadeaccessor method that implements the "appearance" to get the name of the component (service or interface), and then from the Laravel service container static:: $app [$name] (app is registered in Registerfacades in the "appearance") to resolve the related services.
Here we analyze the basic workings of the "look and feel" service.
Also some details about the "look" component, such as:
Or you need to go deep into the facade base class to find out.
Literacy Arrayaccess Interface
Another knowledge point is about static:: $app [$name] this sentence code. You do not have to ask, this is what good to add, is not a simple to get data.
Get the data is not false, simple is not false.
But if you look closely, you will find static :: $app static member variable is not a \illuminate\contracts\foundation\application implementation instance, How can I get a value from an array in an object?
This is because our service container Illuminate\container\container implements the arrayaccess interface.
The function of this interface is to provide an interface that accesses an object like an array, so that an object access member can be accessed like an array.
/** * @link https://github.com/laravel/framework/blob/5.6/src/Illuminate/Container/Container.php */class Container Implements Arrayaccess, containercontract{ /** * Get the value at a given offset. Gets the value of an offset position that actually resolves the service from the container. */Public function Offsetget ($key) { return $this->make ($key);} }
laravel"Appearance" Basic use
A typical usage scenario for a façade service is to use route::get ('/', ...)when defining a route. Such a look seems to "laravel alias service" is not so mysterious. "
The above is the whole content of this article, I hope that everyone's learning has helped, more relevant content please pay attention to topic.alibabacloud.com!