所以这可能是一个相当简单的问题,但我似乎找不到一个非常直接的答案。 我应该可以继续阅读源代码,直到我弄清楚为止,但我希望对这样做的过程有所了解。
我了解 IoC 和依赖注入,我当然在这两个方面都不是很有经验,但我非常了解他们想要实现的目标。 那么这个Laravel是如何实例化到静态实例的呢? 我知道它使用 PHP 反射,但我仍然迷失了从非静态方法到静态方法的部分。 我也知道Laravel不是实现这种设计的唯一框架,但它是我首选和最容易理解的框架。
当您在外观上调用静态方法时,它由Facade
类上的魔术__callStatic方法处理。此方法获取为外观提供服务的基础类,并代理对它的静态调用。
让我们看一个示例外观:
<?php
class MyFacade extends Facade {
public function getFacadeAccessor() { return "MyFacade"; }
}
在这个例子中,当我们以静态方式调用类时,例如: MyFacade::doSomething()
类上不存在静态方法。但是,基础Facade
基类包含将调用的__callStatic
方法。
外观类源代码
public static function __callStatic($method, $args)
{
$instance = static::resolveFacadeInstance(static::getFacadeAccessor());
switch (count($args))
{
case 0:
return $instance->$method();
// Snipped for brevity...
然后,此方法查找基础类以服务于外观。如果外观上的 getFacadeAccessor
方法返回字符串,则使用应用程序的 IOC 容器中的匹配条目(即 $app['MyFacade']
)。如果我们从 getFacadeAccessor
方法返回一个对象,它将被使用(即 public function getFacadeAccessor(){ return new MyClass(); }
原来是拉拉维尔在引擎盖下实例化类!在这个网站中,这家伙通过使用它来创建一个新的立面,让你更多地了解拉拉维尔的核心。顺便说一下,他解释了山雀是如何工作的!
实际上,这很简单:
1 - 你创建一个类,它通过单个调用从 Laravel 的Facade
类扩展,如下所示:
<?php namespace Name'Space;
use Illuminate'Support'Facades'Facade;
class MyClass extends Facade {
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor() { return 'myclass'; }
}
。这让拉拉维尔寻找$app['myclass']
.因此,ServiceProvider
会将myclass
绑定到MyClass
(根据拉拉维尔的约定)。
2 - 为此,当然,您必须创建一个服务提供商。服务提供商将负责退还您可能想要"变成门面"的类的namespace
,在本例中为Name'Space
。
3 - 您必须在app/config/app.php
的providers
数组中注册服务提供商。
现在,如果你更仔细地观察,你会发现Laravel所做的只是导入一个命名空间,并理解它也是一个类。在引擎盖下,它将调用一个实例,但对于用户(程序员)来说,它看起来像一个静态调用。
我希望我已经清楚了!看看我给你的链接,玩得开心!:D