视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Laravel Facade 的详细解读
2020-11-27 14:00:07 责编:小采
文档


下面由Laravel教程栏目给大家介绍Laravel Facade 的详细解读,希望对需要的朋友有所帮助!

大家好,今天带来的内容是 Laravel 的 Facade 机制实现原理。

Facade的简单使用

数据库的使用:

$users = DB::connection('foo')->select(...);

IOC容器

众所周知,IOC容器是 Laravel 框架的最最重要的部分。它提供了两个功能,IOC和容器。

  • IOC(Inversion of Control),也叫控制反转。说白了,就是控制对象的生成,使开发者不用关心对象的如何生成,只需要关心它的使用即可。
  • 而通过IOC机制生成的对象实例需要一个存放的位置,以便之后继续使用,便是它的容器功能。
  • 这次不准备讲解IOC容器的具体实现,之后会有文章详细解读它。关于IOC容器,读者只需要记住两点即可:

    1. 根据配置生成对象实例;
    2. 保存对象实例,方便随时取用;

    简化后 Facade 类

    <?php
    namespace facades;
    
    abstract class Facade
    {
     protected static $app;
    
     /** 
     * Set the application instance.
     *
     * @param \Illuminate\Contracts\Foundation\Application $app
     * @return void
     */
     public static function setFacadeApplication($app)
     { 
     static::$app = $app;
     } 
    
     /** 
     * Get the registered name of the component.
     *
     * @return string
     *
     * @throws \RuntimeException
     */
     protected static function getFacadeAccessor()
     {
     throw new RuntimeException('Facade does not implement getFacadeAccessor method.');
     }
    
     /** 
     * 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)
     {
     return static::$app->instances[$name];
     }
    
     public static function __callStatic($method, $args)
     {
     $instance = static::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);
     } 
     }
    }

    代码说明:

    1. $app中存放的就是一个IOC容器实例,它是在框架初始化时,通过 setFacadeApplication() 这个静态方法设置的
    2. 它实现了 __callStatic 魔术方法
    3. getFacadeAccessor() 方法需要子类去继承,返回一个string的标识,通过这个标识,IOC容器便能返回它所绑定类(框架初始化或其它时刻绑定)的对象
    4. 通过 $instance 调用具体的方法

    创建自己的Facade:

    TEST1 的具体逻辑:

    <?php
    class Test1{
    	public function hello()
    	{
    	print("hello world");
    	}}

    TEST1 类的Facade:

    <?php
    namespace facades;/**
     * Class Test1
     * @package facades
     *
     * @method static setOverRecommendInfo [设置播放完毕时的回调函数]
     * @method static setHandlerPlayer [明确指定下一首时的执行类]
     */class Test1Facade extends Facade{
     protected static function getFacadeAccessor()
     { 
     return 'test1';
     } }

    使用:

    use facades\Test1Facade;Test1Facade::hello(); // 这是 Facade 调用

    解释:

    1. facades\Test1Facade 调用静态方法 hello() 时,由于没有定义此方法,会调用 __callStatic;
    2. 在 __callStatic 中,首先是获取对应的实例,即 return static::$app->instances[$name];。这其中的 $name,即为 facades\Test1 里的 test1
    3. $app, 即为 IOC 容器,类的实例化过程,就交由它来处理。

    下载本文
    显示全文
    专题