【问题标题】:Laravel 4 : How are Facades resolved?Laravel 4:外观如何解决?
【发布时间】:2013-12-17 03:50:21
【问题描述】:

我有点了解 Laravel 4 facades 的底层情况。

我们以这个 Facade 为例:

File::get(someArgs);

如果我没记错的话,一步一步(过于简单)的调用将是:

//static method invocation which are all extended from Facade class
File::__callStatic(get, someArgs)
//returns an instance of FileSystem
File::resolveFacedeInstance('files') 
FileSystem->get(someArgs)

我感到困惑的是下面的方法 File::resolveFacadeInstance() 的注释行:

protected static function resolveFacadeInstance($name)
{
    if (is_object($name)) return $name;

    if (isset(static::$resolvedInstance[$name]))
    {
        return static::$resolvedInstance[$name];
    }



    /**
    * The line that i'm confused about
    */

    return static::$resolvedInstance[$name] = static::$app[$name];
}

我的问题是:

  • File::$app 是如何在 Facade 类中初始化或赋值的
  • 如果 File::get() 是调用的 Facade

    static::$app[$name] 将解析为我认为 Application['files'] 或 Application->files 依次调用 Application->__get('files') 因为在 Application 类中没有 files 属性。

    如果这只是这个方法的内容,FileSystem 类会如何返回?

    public function __get($key)
    {
        return $this[$key];
    }
    

【问题讨论】:

    标签: php laravel laravel-4


    【解决方案1】:

    我会尽量简述:

    所以,你已经知道 resolveFacadeInstance 方法是通过 Facade 类的 __callStatic 方法调用的,组件的 Facade (i.e. File extends Facade) 扩展了这个 Facade 类。

    在框架的启动过程中,从public/index.php下面一行开始执行bootstrap/start.php文件

    $app = require_once __DIR__.'/../bootstrap/start.php';
    

    所以,在这个 (bootstrap/start.php) 文件中,你可以看到一些类似的代码

    // the first line, initiate the application
    $app = new Illuminate\Foundation\Application;
    // ...
    // ...
    // notice this line
    require $framework.'/Illuminate/Foundation/start.php';
    // ...
    // last line
    return $app;
    

    在这段代码 sn-p 中,require $framework.'/Illuminate/Foundation/start.php'; 行开始执行Foundation/start.php 文件,在这个文件中你可能会看到类似这样的内容

    // ...
    
    Facade::clearResolvedInstances();
    // Notice this line
    Facade::setFacadeApplication($app);
    

    这行(如上所示)将application instanse 设置为Facade 类中的$app 属性

    // support/Facades/Facade.php
    public static function setFacadeApplication($app)
    {
        static::$app = $app;
    }
    

    然后在底部的Foundation/start.php文件中,可以看到类似这样的东西

    /*
    |--------------------------------------------------------------------------
    | Register The Core Service Providers
    |--------------------------------------------------------------------------
    |
    | The Illuminate core service providers register all of the core pieces
    | of the Illuminate framework including session, caching, encryption
    | and more. It's simply a convenient wrapper for the registration.
    |
    */
    
    $providers = $config['providers'];
    
    $app->getProviderRepository()->load($app, $providers);
    
    $app->boot();
    

    在上面给出的这段代码sn-p中,框架注册的所有核心组件,正如你所知,每个组件都有一个服务提供者类(即FilesystemServiceProvider),每个服务提供者类都有一个方法@ 987654342@ 是(对于FilesystemServiceProvider

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app['files'] = $this->app->share(function() { return new Filesystem; });
    }
    

    好吧,在这种情况下,$this->app['files'] 设置 (return new Filesystem) 一个匿名函数,它在执行时返回 filesystem

    $this->app['files'] = $this->app->share(function() { return new Filesystem; });
    

    $app['files'] 因此,当您调用File::get() 时,它最终会调用匿名函数,在这种情况下,是以下行

    return static::$resolvedInstance[$name] = static::$app[$name];
    

    调用static::$app['file'];的函数,该函数返回实例,但在返回之前,它将实例存储在$resolvedInstance变量中,因此,下次它可以从变量中返回实例,而无需再次调用匿名函数。 所以,看起来是这样的,static::$resolvedInstance[$name] = static::$app[$name]; 调用了返回实例的匿名函数,并且这个函数是在 app 通过启动过程启动时注册的。

    重要:

    Application 扩展 ContainerContainer 扩展 ArrayAccess 类,这就是为什么 $app 对象的属性可以使用数组表示法(访问)设置/获取。

    我试图给你一个想法,但你必须一步一步地查看代码,你不会只读取/跟踪一次代码。

    【讨论】:

    • 谢谢。我去查一下真的很感谢你的努力。我什至不知道从哪里开始阅读源代码。你真的帮了大忙。
    • 欢迎您!很高兴它有帮助:-)
    • 非常感谢您的解释!
    猜你喜欢
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 2013-01-20
    • 2014-11-16
    • 2013-06-10
    • 2014-02-17
    • 2021-07-22
    • 2014-04-04
    相关资源
    最近更新 更多