2

所以这可能是一个相当简单的问题,但我似乎无法找到一个非常直接的答案。我应该可以继续阅读源代码,直到我弄明白为止,但我希望对这样做的过程有所了解。

我了解 IoC 和依赖注入,当然我在这两个方面都不是很有经验,但我很了解他们想要完成的工作。那么这个 Laravel 是如何实例化为静态实例的呢?我知道它使用 PHP 反射,但我仍然迷失在从非静态方法到静态方法的过程中。我也知道 Laravel 不是实现这种设计的唯一框架,但它是我最喜欢和最容易理解的框架。

4

2 回答 2

4

当您在外观上调用静态方法时,它正在由类上的魔术__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(); }

于 2013-10-30T15:25:33.133 回答
0

事实证明,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将绑定myclassMyClass(根据 Laravel 的约定)。

2 - 为此,当然,您必须创建一个Service Providernamespace在这种情况下,服务提供者将负责返回Name\Space您可能想要“变成外观”的类。

3 - 您必须providersapp/config/app.php.

现在,如果你仔细观察,你会发现 Laravel 所做的只是导入一个命名空间并将其理解为一个类。在后台,它会调用一个实例,但对于用户(程序员)来说,它看起来像是一个静态调用。

我希望我已经清楚了!看看我给你的链接,玩得开心!:D

于 2013-10-30T14:30:24.243 回答