laravel基础之门面

laravel基础之门面

问题

使用laravel的时候一直有个疑问,当出现下面场景的时候,会很好奇的想看看Cookie这个类里的方法,这样也能知道调用方法的时候需要用什么样的值。

1565836380184.png

可是当进去到Cookie类的时候发现里面是这样的

1565836528748.png

只有三个方法,没有所调用的queue方法,这就很奇怪了。

这里就涉及到一个叫门面的概念。

官方描述

Facade,一般翻译成外观或者门面。在 Laravel 的翻译文档中,是不翻词,这里我也直接使用 Facade 来表述。 Facade 的主要作用,是 简化类调用的快捷语法 。因为在结构复杂,功能完善的框架中,往往类的结构,层次也比较复杂,Laravel 也是如此复杂的框架,因此为了简化使用,我们就定义了类的快捷访问方式,在 Laravel 中,就是 Facade! 常规设计模式中的外观模式(Facade Pattern),就是解决快捷访问问题的,因此 Laravel 的 Facade 就是外观模式的实现。可以参考关于外观模式的说明,来进一步了解。

简而言之

门面就是一个为容器中对象提供访问方式的类。该机制原理由 Facade 类实现。Laravel 自带的门面,以及我们创建的自定义门面,都会继承自 Illuminate\Support\Facades\Facade 基类。

门面类只需要实现一个方法:getFacadeAccessor。正是 getFacadeAccessor 方法定义了从容器中解析什么,然后 Facade 基类使用魔术方法 __callStatic() 从你的门面中调用解析对象。

引用自http://blog.onlywan.cc/15010724959148.html文章

分析

我们可以从描述中看到,是通过一个getFacadeAccessor 的静态方法来定义需要从容器中解析的对象。

vendor\laravel\framework\src\Illuminate\Support\Facades\Cookie.php 这是Cookie的门面文件

cookie($key, null));
    }

    /**
     * Retrieve a cookie from the request.
     *
     * @param  string  $key
     * @param  mixed   $default
     * @return string
     */
    public static function get($key = null, $default = null)
    {
        return static::$app['request']->cookie($key, $default);
    }

    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'cookie';
    }
}


Cookie 门面继承了 Facade 基类并定义了getFacadeAccessor 方法,该方法的工作就是返回服务容器绑定类的别名,当用户引用 Cookie 类的任何静态方法时,Laravel 从服务容器中解析 cookie 绑定,然后在解析出的对象上调用所有请求方法。

那么如何绑定cookie的呢,是通过 config/app.php 中 providers 的Illuminate\Cookie\CookieServiceProvider::class 绑定的

1565837587758.png

这个Illuminate\Cookie\CookieServiceProvider::class类就是Cookie的服务提供者

1565837748356.png
app->singleton('cookie', function ($app) {
            $config = $app->make('config')->get('session');

            return (new CookieJar)->setDefaultPathAndDomain($config['path'], $config['domain'], $config['secure']);
        });
    }
}

服务提供者就是负责实例化cookie的类 ,并且注册到容器里面去。这里绑定的cookie就和getFacadeAccessor 方法的返回值是一样的。在这里,Cookie用的是CookieJar这个类,所以调用的是这个类里的queue方法。

1565838018453.png
1565838032502.png
[图片上传中...(1565838278260.png-8b476c-1565840701199-0)]

Facade 基类

前面说了Cookie 门面继承了 Facade 基类

1565838278260.png

所以只需要调用getFacadeAccessor方法,就可以调用到CookieJar类里的方法了

先看下Facade基类

vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php

1565838384848.png

有一个__callStatic魔术方法方法

__callStatic() 魔术方法作用:当调用当前环境下未定义或不可见的类属性或方法时,该方法会被调用。

就是当你调用queue方法是,会执行到这里。

先分析下方法

$instance = static::getFacadeRoot();

调用了getFacadeRoot方法

1565838538968.png

在方法里又调用了resolveFacadeInstance方法,这里传的参数就是Cookie门面里面的静态方法static::getFacadeAccessor(),返回的就是’cookie‘。

注:这里涉及到php父类调用子类静态方法的方式,使用static关键字,忘了的同学需要去补一下

如果Cookie门面没有getFacadeAccessor方法,就会调用自身的getFacadeAccessor方法

1565838729927.png

就会抛出异常。

resolveFacadeInstance方法的内容:

1565838758943.png
1565838809657.png

进来方法先查看实例是否在$resolvedInstance列表中,如果在就直接使用,不存在就通过$app获取

首次进来肯定是通过$app获取的

分析$app来源

1565839179094.png

权限是protected,是通过setFacadeApplication方法实现的

1565839208150.png

这里应该是有某个方法或者类里调用了这个方法,通过查找发现是 Laravel 框架在初始化 Http Kernel 时初始化的

bootstrap/app.php文件中

singleton(
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);

$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);

/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/

return $app;
1565839615100.png

[图片上传中...(1565839725805.png-77d17f-1565841047391-0)]

vendor\laravel\framework\src\Illuminate\Foundation\Console\Kernel.php文件里的$bootstrappers

1565839725805.png
image.png

通过传递$app,所以才有了应用列表

参考文章链接:http://blog.onlywan.cc/15010724959148.html

你可能感兴趣的:(laravel基础之门面)