我有点看看Laravel 4 幕墙下面发生了什么.
我们以此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->文件,它们又调用Application - > __ get('files'),因为Application类中没有 files属性.
如果只是这个方法的内容,FileSystem类将如何返回?
public function __get($key) { return $this[$key]; }
The Alpha.. 21
我将简要介绍一下:
所以,你已经知道resolveFacadeInstance
通过类的方法调用该__callStatic
方法,Facade
并且组件的Facade (i.e. File extends Facade)
扩展了这个Facade
类.
在框架的启动过程中,从public/index.php
以下行开始执行bootstrap/start.php
文件
$app = require_once __DIR__.'/../bootstrap/start.php';
所以,在this(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;
在此代码段中,require $framework.'/Illuminate/Foundation/start.php';
行开始执行Foundation/start.php
文件,在此文件中您可能会看到类似这样的内容
// ... Facade::clearResolvedInstances(); // Notice this line Facade::setFacadeApplication($app);
这个(上面给出的)行将application
instanse 设置$app
为Facade
类中的属性
// 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();
在上面给出的代码片段中,框架注册的所有核心组件,如您所知,每个组件都有一个服务提供者类(即FilesystemServiceProvider
),并且在每个服务提供者类中都有一个方法register
(for 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];
调用函数for static::$app['file'];
并且此函数返回实例但在返回之前,它将实例存储在$resolvedInstance
变量中,因此,下次它可以从变量返回实例而不再调用匿名函数.因此,它看起来像是,static::$resolvedInstance[$name] = static::$app[$name];
调用匿名函数返回实例,并且当app
通过启动过程启动时,此函数已在之前注册.
重要:
Application
扩展Container
和Container
扩展ArrayAccess类,这就是为什么,$app
使用数组表示法可以(访问)set/get对象的属性.
我试图给你一个想法,但你必须一步一步查看代码,你不会只阅读/跟踪代码一次.
我将简要介绍一下:
所以,你已经知道resolveFacadeInstance
通过类的方法调用该__callStatic
方法,Facade
并且组件的Facade (i.e. File extends Facade)
扩展了这个Facade
类.
在框架的启动过程中,从public/index.php
以下行开始执行bootstrap/start.php
文件
$app = require_once __DIR__.'/../bootstrap/start.php';
所以,在this(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;
在此代码段中,require $framework.'/Illuminate/Foundation/start.php';
行开始执行Foundation/start.php
文件,在此文件中您可能会看到类似这样的内容
// ... Facade::clearResolvedInstances(); // Notice this line Facade::setFacadeApplication($app);
这个(上面给出的)行将application
instanse 设置$app
为Facade
类中的属性
// 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();
在上面给出的代码片段中,框架注册的所有核心组件,如您所知,每个组件都有一个服务提供者类(即FilesystemServiceProvider
),并且在每个服务提供者类中都有一个方法register
(for 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];
调用函数for static::$app['file'];
并且此函数返回实例但在返回之前,它将实例存储在$resolvedInstance
变量中,因此,下次它可以从变量返回实例而不再调用匿名函数.因此,它看起来像是,static::$resolvedInstance[$name] = static::$app[$name];
调用匿名函数返回实例,并且当app
通过启动过程启动时,此函数已在之前注册.
重要:
Application
扩展Container
和Container
扩展ArrayAccess类,这就是为什么,$app
使用数组表示法可以(访问)set/get对象的属性.
我试图给你一个想法,但你必须一步一步查看代码,你不会只阅读/跟踪代码一次.