Laravel Core Interpretation facades

Source: Internet
Author: User
Tags spl
This article mainly introduces about the Laravel core interpretation of facades, has a certain reference value, now share to everyone, the need for friends can refer to

What is facades

Facades is a component that we use very frequently in the development of laravel applications, called components are not suitable, in fact, they are a set of static class interface or proxy, so that developers can easily access the various services bound to the service container. The explanations for facades in the Laravel documentation are as follows:

facades provides a "static" interface for the classes available in the application's service container. Laravel itself comes with a lot of facades, and even you may already be using them unknowingly! As a "static agent" of the base class within the service container, laravel"facades" has the advantages of simplicity and easy expression, while maintaining a higher testability and flexibility than traditional static methods.

We often use the route is a facade, it is the alias of the \Illuminate\Support\Facades\Route class, this facade class agent is registered to the Service container service router , so through the route class we can easily use the services provided in the router service, The service parsing involved is completely implicit by laravel, which in some way makes the application code much more concise. Below we will take a look at the process of facades from being registered into the Laravel framework to being used by the application. Facades is closely aligned with serviceprovider, so if you understand the middle of these processes, it can be helpful to develop custom laravel components.

Register facades

When it comes to facades registration and the bootstrap phase, which is mentioned many times during the introduction of other core builds, there is a process to start the application before the request is routed through middleware and routing:

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 ());} Boot boot laravel application public Function bootstrap () {if (! $this->app->hasbeenbootstrapped ()) {/** Execute $bootstrap sequentially The Bootstrap () function of each bootstrapper in pers = [' Illuminate\foundation\bootstrap\detectenviron ment ', ' illuminate\foundation\bootstrap\loadconfiguration ', ' illuminate\foundation\bootstrap\conf Igurelogging ', ' illuminate\foundation\bootstrap\handleexceptions ', ' Illuminate\foundation\bootstra P\registerfacades ', ' Illuminate\foundAtion\bootstrap\registerproviders ', ' illuminate\foundation\bootstrap\bootproviders ',];*/    $this->app->bootstrapwith ($this->bootstrappers ()); }}

This phase registers the facades used in the application during the launch of the app Illuminate\Foundation\Bootstrap\RegisterFacades .

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 ();}    }

In this AliasLoader case, an instance of the class will register aliases for all facades, and the correspondence between facades and aliases is stored in config/app.php an array of files. $aliases

' Aliases ' = [    ' App ' = Illuminate\support\facades\app::class,    ' Artisan ' and ' = illuminate\support\ Facades\artisan::class,    ' Auth ' = Illuminate\support\facades\auth::class,    ...    ' Route ' = = Illuminate\support\facades\route::class,    ...]

Look at how the aliases are registered in the Aliasloader.

Class:illuminate\foundation\aliasloaderpublic 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 () {    //puts Aliasloader::load () into the auto-load function queue and puts it in the queue header    Spl_autoload_ Register ([$this, ' Load '], true, true);}

You can see from the code snippet above that Aliasloader registers the load method with the head of the SPL __autoload function queue. Take a look at the source code of the Load method:

Public function Load ($alias) {    if (isset ($this->aliases[$alias]) {        return Class_alias ($this aliases[$alias], $alias);}    }

In the Load method $aliases , the facade class in the configuration creates a corresponding alias, for example, when we use the alias class Route , PHP uses the Aliasloader load method to Illuminate\Support\Facades\Route::class create an alias class for the class Route , so we use it Route in the program. Actually, the class is used `Illuminate\Support\Facades\Route .

Parsing services for Facade agents

Facades registered to the framework after we can use the facade in the application, such as the registration of routes we often use Route::get('/uri', 'Controller@action); , then Route how to proxy to the routing service, which involves in the facade service implicit parsing, Let's take a look at the source code of the route class:

Class Route extends facade{    /**     * Get The registered name of the component.     *     * @return String     *    /protected static function Getfacadeaccessor ()    {        return ' router ';    }}

There is only one simple method, and no, no, no, no, wait for the get post delete routing method, not in the parent class, but we know the static method that triggers PHP when calling a static method that does not exist. __callStatic

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);} Get facade root Object public static function Getfacaderoot () {    return static::resolvefacadeinstance (static:: Getfacadeaccessor ());} /** * resolves facade corresponding service */protected static function Resolvefacadeinstance ($name) {    if (Is_object ($name)) from the service container {        return $name;    }    if (Isset (static:: $resolvedInstance [$name])) {        return static:: $resolvedInstance [$name];    }    return static:: $resolvedInstance [$name] = static:: $app [$name];}

by accessor (string router) set in the subclass route facade, the corresponding service is resolved from the service container, The router service is registered in the service container at the Registerbaseserviceproviders stage of the application initialization (which can be seen in the application construction method) \Illuminate\Routing\RoutingServiceProvider :

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);        }    ......}

The class that corresponds to the router service is \Illuminate\Routing\Router , so the Route facade actually proxies the class, and Route::get actually calls the \Illuminate\Routing\Router object's Get method

/** * 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);}

Add two points:

    1. The parsing service static::$app is set at the very beginning RegisterFacades , and it refers to the service container.

    2. Static:: $app [' router ']; the router service can be parsed from the service container in the form of array access because the service container implements the Arrayaccess interface for SPL, which is not a concept to look at official documents Arrayaccess

Summarize

By combing the facade registration and use process we can see that facade and service providers (serviceprovider) are closely aligned, So if you write Laravel custom service later on, in addition to registering the service into the service container through the component's serviceprovider, you can also provide a facade in the component that allows the application to easily access the custom services you write.

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!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.