首页 > 编程 > PHP > 正文

Laravel5学习四:Facade的运行机制

2020-03-22 17:41:39
字体:
来源:转载
供稿:网友
  • 什么是Facades

    官方文档如是说:

    Facades 提供一个 静态接口 给在html' target='_blank'>应用程序的 服务容器 中可以取用的类。Laravel 附带许多 facades,甚至你可能已经在不知情的状况下使用过它们!Laravel 的「facades」作为在 IoC 容器里面的基础类的静态代理,提供的语法有简洁、易表达的优点,同时维持比传统的静态方法更高的可测试性和弹性。

    说实话,这段话读起来真不像人类的语言,我准备来拆解一下。
    首先, Facades 是一个类,是一个什么类呢?它是基础类的一个静态代理。
    其次, Facades 是可以直接从IOC容器中拿到的,对应到laravel5就是说,可以直接使用,它已经存在于app这个容器中。
    最后, 为什么要有 Facades 这个东东?首先优点是:它提供的语法更简洁,易表达。这个其实不是主要原因,个人觉得最主要的原因是:便于可测试性与降低耦合性(代理模式的优点)

    用例子来说明

    PS:本部分内容参考自网络:原文地址

    我们知道$app 在laravel中是一个特殊的全局变量,它在最初启动的时候就是ioc容器的对象实例。
    于是如果我们要取从ioc容器中取一个实例出来,是这样写的:

    $value = $app->make('cache')->get('key');

    由于$app implements PHP的 ArrayAccess interface,所以可以更简化点,写成:

    $value = $app['cache']->get('key');

    你甚至可以用函数的方式写成这样:

    $value = app('cache')->get('key');

    这个时候Facace跳出来说,我可以写成这样:

    $value = Cache::get('key');

    运行机制分析Facades 的命名空间
    相信只要玩过laravel的人,都会见过当遇到 Facades 的时候,导入命名空间,只需要用 use XXX 即可。不用把完整的的命名空间写出来。这是为什么?
    正常的类的命名空间,应该这样写:
    use Illuminate/Support/Facades/Cache;

    Facades 只需要这样写:

    use Cache;

    为什么能够这样?我看了一些它的运行过程,解析如下:
    这里写图片描述
    这幅图,中的关键点是:AliasLoader中注册的自动加载方法,它使用了我们在app.php配置中的 aliases 数组,从而通过这个别名,可以找到对应的真实类存在的文件,然后完成对象的实例化。

    如何构建自己的 Facades
    PS:还是以 Cache 为例子

    首先需穴ky"http://www.it165.net/qq/" target="_blank" class="keylink">qq5ub2otcS+zcrHQ2FjaGXV4rj2wOCxvsnto6zKtc/Wy/y1xLmmxNyho9XiwO+21NOmtcTOxLz+ysejuiA8YnI+CklsbHVtaW5hdGVcQ2FjaGVcQ2FjaGVNYW5hZ2VyICixuNeio7rTydPaQ2FjaGXT0Lbg1tbKtc/Wo6zS8rTLzai5/bncwO3V38C0u/HIoc/r0qq1xENhY2hlyrXP1re9sLihoyk8L3A+Cgo8cD61sUNhY2hl1eK49sDgo6zQtLrD1q6686OsztLDx9KqvavL/LDztqi1vdK7uPa3/s7xzOG5qdXfwO+x38ilo6zV4sDvtcS3/s7xzOG5qdXfzrvWw8rHo7ogPGJyPgpJbGx1bWluYXRlXENhY2hlXENhY2hlU2VydmljZVByb3ZpZGVyIKOssPO2qLK/t9a0+sLrysejujwvcD4KCgoKPHByZSBjbGFzcz0="brush:java;">public function register(){ $this->app->singleton('cache', function ($app) { return new CacheManager($app); }); ...... }

    这里需要注意的是,绑定时,为什么要使用’cache’ 这个字符串,后面会讲到。当服务提供者写好后,需要在 app.php 的 providers 的数组中配置服务提供者,此处代码如下:

    'providers' => [    /*    * Laravel Framework Service Providers...    */    Illuminate/Foundation/Providers/ArtisanServiceProvider::class,    Illuminate/Auth/AuthServiceProvider::class,    Illuminate/Broadcasting/BroadcastServiceProvider::class,    Illuminate/Bus/BusServiceProvider::class,    Illuminate/Cache/CacheServiceProvider::class,    ......]

    完成以下步骤后,就可以构建 Facades 类了,Cache 的 Facades 的位置在 Illuminate/Support/Facades/Cache 。

    <?phpnamespace Illuminate/Support/Facades;/** * @see /Illuminate/Cache/CacheManager * @see /Illuminate/Cache/Repository */class Cache extends Facade{    /**     * Get the registered name of the component.     *     * @return string     */    protected static function getFacadeAccessor()    {        return 'cache';    }}

    所有的 Facades 类都需要继承自 Facades ,并实现 getFacadeAccessor 方法。它的工作是定义要从容器解析什么。这也就是说,如果我们绑定的时候,写的是 cache ,那么这里也需要返回 cache ,要不然解析的时候,就会找不到。大家可以试试改成其它名字。
    最后一步,需要配置 app.php 中的 aliases 数组,这涉及到 Facades 的自动加载。就是最开始画的那幅图。

    'aliases' => [    'App'       => Illuminate/Support/Facades/App::class,    'Artisan'   => Illuminate/Support/Facades/Artisan::class,    'Auth'      => Illuminate/Support/Facades/Auth::class,    'Blade'     => Illuminate/Support/Facades/Blade::class,    'Bus'       => Illuminate/Support/Facades/Bus::class,    'Cache'     => Illuminate/Support/Facades/Cache::class,    ......    ]

    到这里, Facades 的运行解析机制,以及怎样创建自己的 Facades 都已经讲解完毕。
    希望对大家有帮助,转载请注明出处!

    PHP编程

    郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

  • 发表评论 共有条评论
    用户名: 密码:
    验证码: 匿名发表