Trong bài viết này mình sẽ giới thiệu về facade và alias trong laravel

Môi trường khảo sát

Trong bài viết này môi trường khảo sát sẽ theo version sau của laravel

Laravel 5.5.x

Những phiên bản cũ có thể khác với phiên bản mới nhất, thực tế là nó khác nhau.
Hãy chú ý đến điểm đó

Ví dụ sử dụng Facade

Ví dụ trong laravel bạn muốn ghi log vào laravel.log thì bạn phải sử dụng Log

<? php

use  Log ;

...

class  SampleController  extends  Controller  
{

    public  function  index ()  
    { 
        Log :: info ( 'info message' );

        ....

Trên ví dụ trên bạn thấy việc ghi log chỉ việc sử dụng class Log và phương thức static của nó, vậy class Log này nó được load vào khi nào?

Giới thiệu về Facade

Ở ví dụ thực ra class Log chính là IlluminateSupportFacadesLog, tuy nhiên ở trên bạn có thể gọi được như trên là thông qua alias

Trong khi implement class Log, bạn xem code sẽ có hàm sau

/**
 * @see IlluminateLogWriter
 */
class Log extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return LoggerInterface::class;
    }
}
   

Code tạo 1 facade trông rất đơn giản, vậy thì việc gọi những hàm ::info, ::warning, ::debug … ở đâu, vì những hàm này đều là những hàm public , vậy bạn hãy lên trên class cha Facade
Bạn sẽ thấy hàm sau, nó sẽ đóng vai trò gọi các hàm public

     /**
     * Handle dynamic, static calls to the object.
     *
     * @param  string  $method
     * @param  array   $args
     * @return mixed
     *
     * @throws RuntimeException
     */
    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);
    }

Hàm __callStatic sẽ thực hiện gọi một phương thức trong class được nạp vào Facade(chỉ phương thức default, public, static), trên hàm trên bạn thấy có gọi hàm getFacadeRoot, code của hàm này như dưới

     /**
     * Get the root object behind the facade.
     *
     * @return mixed
     */
    public static function getFacadeRoot()
    {
        return static::resolveFacadeInstance(static::getFacadeAccessor());
    }
    
     /**
     * Resolve the facade root instance from the container.
     *
     * @param  string|object  $name
     * @return mixed
     */
    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];
    }

Trong hàm trên sẽ thực hiện tìm kiếm những instance từ DI container đã được đăng ký trong application dựa vào name
name này sẽ được đăng ký ở hàm getFacadeAccessor

Giới thiệu về Alias

Trong cấu trúc laravel bạn sẽ khai báo các alias ở trong config/app.php

    /*
    |--------------------------------------------------------------------------
    | Class Aliases
    |--------------------------------------------------------------------------
    |
    | This array of class aliases will be registered when this application
    | is started. However, feel free to register as many as you wish as
    | the aliases are "lazy" loaded so they don't hinder performance.
    |
    */

    'aliases' => [

        'App' => IlluminateSupportFacadesApp::class,
        'Artisan' => IlluminateSupportFacadesArtisan::class,
        ...
        'Log' => IlluminateSupportFacadesLog::class,
        ...

Các alias được đăng ký và load dự trên function spl_autoload_register,
các aliases được load ở trong class AliasLoader.php

     /**
     * Prepend the load method to the auto-loader stack.
     *
     * @return void
     */
    protected function prependToLoaderStack()
    {
        spl_autoload_register([$this, 'load'], true, true);
    }

Việc sử dụng facade trong laravel giống như là các util rất là dễ dàng, bên cạnh đó có thể viết các helper dùng facade

Ví dụ

Sau đây là ví dụ tạo 1 facade trong laravel
https://github.com/ngodinhngoc/laravel_tip/pull/1/files

Các bạn có thể tham khảo cách tạo 1 facade, nó cũng gần giống như là tạo 1 helper trong laravel!