Facade 的运行机制

php中文网
发布: 2016-06-20 12:26:35
原创
2097人浏览过

门面为应用的服务容器中的绑定类提供了一个“静态”接口。该机制原理由 facade 类实现,laravel 自带的门面,以及创建的自定义门面,都会继承自 illuminate\support\facades\facade 基类。

(用Route来举例)

机制流程图:

facade顶层调用

config/app.php'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,        'Cache' => Illuminate\Support\Facades\Cache::class,        'Config' => Illuminate\Support\Facades\Config::class,        'Cookie' => Illuminate\Support\Facades\Cookie::class,        'Crypt' => Illuminate\Support\Facades\Crypt::class,        'DB' => Illuminate\Support\Facades\DB::class,        'Eloquent' => Illuminate\Database\Eloquent\Model::class,        'Event' => Illuminate\Support\Facades\Event::class,        'File' => Illuminate\Support\Facades\File::class,        'Gate' => Illuminate\Support\Facades\Gate::class,        'Hash' => Illuminate\Support\Facades\Hash::class,        'Lang' => Illuminate\Support\Facades\Lang::class,        'Log' => Illuminate\Support\Facades\Log::class,        'Mail' => Illuminate\Support\Facades\Mail::class,        'Password' => Illuminate\Support\Facades\Password::class,        'Queue' => Illuminate\Support\Facades\Queue::class,        'Redirect' => Illuminate\Support\Facades\Redirect::class,        'Redis' => Illuminate\Support\Facades\Redis::class,        'Request' => Illuminate\Support\Facades\Request::class,        'Response' => Illuminate\Support\Facades\Response::class,        'Route' => Illuminate\Support\Facades\Route::class,  //例如我们看Route,平时我们调用Route::get这样,其实是调用alias的Route,然后这个Route指向了Illuminate\Support\Facades\Route这个类,至于为什么能实现这种机制,需要继续分析        'Schema' => Illuminate\Support\Facades\Schema::class,        'Session' => Illuminate\Support\Facades\Session::class,        'Storage' => Illuminate\Support\Facades\Storage::class,        'URL' => Illuminate\Support\Facades\URL::class,        'Validator' => Illuminate\Support\Facades\Validator::class,        'View' => Illuminate\Support\Facades\View::class,        'Form' => Collective\Html\FormFacade::class,        'Html' => Collective\Html\HtmlFacade::class,    ],
登录后复制

Route.php

(用phpstome的话,comm+b 就能够通过类名找到类所在的源码)

一览运营宝
一览运营宝

一览“运营宝”是一款搭载AIGC的视频创作赋能及变现工具,由深耕视频行业18年的一览科技研发推出。

一览运营宝 41
查看详情 一览运营宝
vendor/laravel/framework/src/Illuminate/Support/Facades/Route.php< ?phpnamespace Illuminate\Support\Facades;/** * @see \Illuminate\Routing\Router */class Route extends Facade{    /**     * Get the registered name of the component.     *     * @return string     */    protected static function getFacadeAccessor()  //只知道Route这个类是继承了Facade,并且有一个静态方法getFacadeAccessor,返回一个router的字符串,这是一个静态方法,    {        return 'router';    }}
登录后复制

当我们使用 Route::get(); 时候其实可以看到这里并没有静态的get方法,那么就会调用Facade的魔术方法__callStatic

再次进入Facade的源码,找到一个 __callStatic的静态魔术方法

__callStatic :在对对象不存在的静态方法进行调用时自动执行;

vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.phppublic static function __callStatic($method, $args)    {        $instance = static::getFacadeRoot();  //魔术方法调用后这里再次调用一个关键的getFacadeRoot方法,这个是静态调用        if (! $instance) {            throw new RuntimeException('A facade root has not been set.');        }        switch (count($args)) {            case 0:                return $instance->$method();            case 1:                return $instance->$method($args[0]);            case 2:                return $instance->$method($args[0], $args[1]);            case 3:                return $instance->$method($args[0], $args[1], $args[2]);            case 4:                return $instance->$method($args[0], $args[1], $args[2], $args[3]);            default:                return call_user_func_array([$instance, $method], $args);        }    }
登录后复制

再次进入getFacadeRoot方法的源码(其实也是当前facade文件)

vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php    /**     * The resolved object instances.     *     * @var array     */    protected static $resolvedInstance; //这个是一个存放实例的,这个是用来解析出实例的  public static function getFacadeRoot()    {        return static::resolveFacadeInstance(static::getFacadeAccessor()); //运行了2个方法,其中getFacadeAccessor作为了resolveFacadeInstance的参数来传递    }    /**     * Get the registered name of the component.     *     * @return string     *     * @throws \RuntimeException     */    protected static function getFacadeAccessor() //返回和抛出报错信息    {        throw new RuntimeException('Facade does not implement getFacadeAccessor method.');    }    /**     * Resolve the facade root instance from the container.     *     * @param  string|object  $name     * @return mixed     */    protected static function resolveFacadeInstance($name) //这个方法需要的是一个$name变量,这个变量就是getFacadeAccessor(),也就是在vendor/laravel/framework/src/Illuminate/Support/Facades/Route.php这里的返回的字符串,因为route.php重写了getFacadeAccessor方法,所以能够获取到    {        if (is_object($name)) {              return $name;        }        if (isset(static::$resolvedInstance[$name])) {            return static::$resolvedInstance[$name];        }        return static::$resolvedInstance[$name] = static::$app[$name]; //这里是用$app来解析container里面的对象,以前说过的IOC,将这个获取到的关键字放到$app[]来解析,然后将这个解析的container对象存放到$resolvedInstance,然后返回    }
登录后复制
最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号