Table of Contents
What are Facades
Registering Facades
By sorting out the registration and usage process of Facade, we can see that Facade and service provider (ServiceProvider) work closely together Yes, so if you write your own Laravel custom service in the future, in addition to registering the service into the service container through the component's ServiceProvider, you can also provide a Facade in the component so that the application can easily access the custom service you wrote.
Home Backend Development PHP Tutorial Laravel Core Interpretation Facades

Laravel Core Interpretation Facades

Jul 06, 2018 pm 02:45 PM
laravel

This article mainly introduces the core interpretation of Facades in Laravel, which has certain reference value. Now I share it with everyone. Friends in need can refer to it

What are Facades

Facades are A component that we use very frequently in Laravel application development is not appropriately called a component. In fact, they are a set of static class interfaces or proxies that allow developers to simply access various services bound to the service container. The explanation of Facades in the Laravel documentation is as follows:

Facades provide a "static" interface for classes available in the application's service container. Laravel comes with many facades, and you may be using them without even knowing it! As a "static proxy" for base classes in the service container, Laravel "facades" have the advantages of concise and easy-to-express syntax, while maintaining higher testability and flexibility than traditional static methods.

The Route we often use is a Facade, which is an alias of the \Illuminate\Support\Facades\Route class. This Facade class represents the registered in the service container. router service, so through the Route class we can easily use the various services provided in the router service, and the service resolution involved is completely implicitly completed by Laravel, which to a certain extent makes the application The code has become much simpler. Below we will take a brief look at the process between Facades being registered in the Laravel framework and being used by the application. Facades work closely with ServiceProvider, so if you understand these processes, it will be helpful to develop custom Laravel components.

Registering Facades

When it comes to Facades registration, we have to go back to the Bootstrap stage that has been mentioned many times when introducing other core components. There is a startup before the request passes through middleware and routing. Application process:

//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());
    }
}
Copy after login

In the process of starting the applicationIlluminate\Foundation\Bootstrap\RegisterFacadesThis stage will register the Facades used in the application.

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

Here, aliases will be registered for all Facades through instances of the AliasLoader class. The corresponding relationship between Facades and aliases is stored in the config/app.php file. ##$aliasesIn the array

'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,
    ......
]
Copy after login

Look at how these aliases are registered in 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);
}
Copy after login

Through the above code snippet, you can see that AliasLoader registers the load method to the SPL __autoload function The head of the 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);
    }
}
Copy after login

In the load method

$aliases the Facade class in the configuration creates the corresponding alias, for example, when we use the alias class Route PHP will create an alias class Route for the Illuminate\Support\Facades\Route::class class through the load method of AliasLoader, so we use the alias Route in the program In fact, the `Illuminate\Support\Facades\Route class is used.

Resolve Facade proxy service

After registering Facades to the framework, we can use the Facade in the application. For example, when registering routes, we often use

Route::get ('/uri', 'Controller@action);, then how does Route proxy to the routing service? This involves the implicit resolution of the service in the Facade. Let's take a look. 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';
    }
}
Copy after login

has only one simple method, and there are no routing methods such as

get, post, delete, etc., parent class Neither, but we know that calling a static method that does not exist in the class will trigger PHP's __callStaticstatic method

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];
}
Copy after login

through the accessor (string router) set in the subclass Route Facade , parse the corresponding service from the service container. The router service is registered into the service container by

\Illuminate\Routing\RoutingServiceProvider during the registerBaseServiceProviders stage when the application is initialized (see the construction method of Application for details). :

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

The class corresponding to the router service is

\Illuminate\Routing\Router, so Route Facade actually proxies this class, and Route::get actually calls \Illuminate\Routing\RouterThe get method of the object

/**
 * 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);
}
Copy after login
Add two points:

  1. Used when parsing the service

    static::$app is set in the initial RegisterFacades, which refers to the service container.

  2. static::$app['router']; The reason why the router service can be parsed from the service container in the form of array access is because the service container implements the ArrayAccess interface of SPL. There is no such thing as For concepts, you can read the official document ArrayAccess

  3. ##Summary

By sorting out the registration and usage process of Facade, we can see that Facade and service provider (ServiceProvider) work closely together Yes, so if you write your own Laravel custom service in the future, in addition to registering the service into the service container through the component's ServiceProvider, you can also provide a Facade in the component so that the application can easily access the custom service you wrote.

The above is the entire content of this article. I hope it will be helpful to everyone's study. For more related content, please pay attention to the PHP Chinese website!

related suggestion:

Interpretation of Laravel middleware (Middleware)

Interpretation of Laravel routing (Route)

The above is the detailed content of Laravel Core Interpretation Facades. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to get the return code when email sending fails in Laravel? How to get the return code when email sending fails in Laravel? Apr 01, 2025 pm 02:45 PM

Method for obtaining the return code when Laravel email sending fails. When using Laravel to develop applications, you often encounter situations where you need to send verification codes. And in reality...

How to implement the custom table function of clicking to add data in dcat admin? How to implement the custom table function of clicking to add data in dcat admin? Apr 01, 2025 am 07:09 AM

How to implement the table function of custom click to add data in dcatadmin (laravel-admin) When using dcat...

Laravel Redis connection sharing: Why does the select method affect other connections? Laravel Redis connection sharing: Why does the select method affect other connections? Apr 01, 2025 am 07:45 AM

The impact of sharing of Redis connections in Laravel framework and select methods When using Laravel framework and Redis, developers may encounter a problem: through configuration...

Laravel multi-tenant extension stancl/tenancy: How to customize the host address of a tenant database connection? Laravel multi-tenant extension stancl/tenancy: How to customize the host address of a tenant database connection? Apr 01, 2025 am 09:09 AM

Custom tenant database connection in Laravel multi-tenant extension package stancl/tenancy When building multi-tenant applications using Laravel multi-tenant extension package stancl/tenancy,...

Laravel Eloquent ORM in Bangla partial model search) Laravel Eloquent ORM in Bangla partial model search) Apr 08, 2025 pm 02:06 PM

LaravelEloquent Model Retrieval: Easily obtaining database data EloquentORM provides a concise and easy-to-understand way to operate the database. This article will introduce various Eloquent model search techniques in detail to help you obtain data from the database efficiently. 1. Get all records. Use the all() method to get all records in the database table: useApp\Models\Post;$posts=Post::all(); This will return a collection. You can access data using foreach loop or other collection methods: foreach($postsas$post){echo$post->

How to effectively check the validity of Redis connections in Laravel6 project? How to effectively check the validity of Redis connections in Laravel6 project? Apr 01, 2025 pm 02:00 PM

How to check the validity of Redis connections in Laravel6 projects is a common problem, especially when projects rely on Redis for business processing. The following is...

Laravel database migration encounters duplicate class definition: How to resolve duplicate generation of migration files and class name conflicts? Laravel database migration encounters duplicate class definition: How to resolve duplicate generation of migration files and class name conflicts? Apr 01, 2025 pm 12:21 PM

A problem of duplicate class definition during Laravel database migration occurs. When using the Laravel framework for database migration, developers may encounter "classes have been used...

Laravel Introduction Example Laravel Introduction Example Apr 18, 2025 pm 12:45 PM

Laravel is a PHP framework for easy building of web applications. It provides a range of powerful features including: Installation: Install the Laravel CLI globally with Composer and create applications in the project directory. Routing: Define the relationship between the URL and the handler in routes/web.php. View: Create a view in resources/views to render the application's interface. Database Integration: Provides out-of-the-box integration with databases such as MySQL and uses migration to create and modify tables. Model and Controller: The model represents the database entity and the controller processes HTTP requests.

See all articles