所以这可能是一个相当简单的问题,但我似乎无法找到一个非常直接的答案。我应该可以继续阅读源代码,直到我弄明白为止,但我希望对这样做的过程有所了解。
我了解 IoC 和依赖注入,当然我在这两个方面都不是很有经验,但我很了解他们想要完成的工作。那么这个 Laravel 是如何实例化为静态实例的呢?我知道它使用 PHP 反射,但我仍然迷失在从非静态方法到静态方法的过程中。我也知道 Laravel 不是实现这种设计的唯一框架,但它是我最喜欢和最容易理解的框架。
所以这可能是一个相当简单的问题,但我似乎无法找到一个非常直接的答案。我应该可以继续阅读源代码,直到我弄明白为止,但我希望对这样做的过程有所了解。
我了解 IoC 和依赖注入,当然我在这两个方面都不是很有经验,但我很了解他们想要完成的工作。那么这个 Laravel 是如何实例化为静态实例的呢?我知道它使用 PHP 反射,但我仍然迷失在从非静态方法到静态方法的过程中。我也知道 Laravel 不是实现这种设计的唯一框架,但它是我最喜欢和最容易理解的框架。
当您在外观上调用静态方法时,它正在由类上的魔术__callStatic方法处理Facade
。此方法获取为外观提供服务的底层类并代理对其的静态调用。
让我们看一个示例外观:
<?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(); }
事实证明,Laravel 在后台实例化了类!在这个站点中,这个家伙通过使用 Laravel 的核心来创建一个新的门面,让你对它的核心有了更多的了解。顺便说一句,他解释了山雀的工作原理!
它非常简单,实际上:
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'; }
}
...这让 Laravel 寻找$app['myclass']
. 因此,ServiceProvider
将绑定myclass
到MyClass
(根据 Laravel 的约定)。
2 - 为此,当然,您必须创建一个Service Provider。namespace
在这种情况下,服务提供者将负责返回Name\Space
您可能想要“变成外观”的类。
3 - 您必须providers
在app/config/app.php
.
现在,如果你仔细观察,你会发现 Laravel 所做的只是导入一个命名空间并将其理解为一个类。在后台,它会调用一个实例,但对于用户(程序员)来说,它看起来像是一个静态调用。
我希望我已经清楚了!看看我给你的链接,玩得开心!:D