【问题标题】:How laravel uses object as an array in Facade classlaravel 如何在 Facade 类中使用对象作为数组
【发布时间】:2018-11-04 22:37:09
【问题描述】:

我注意到,为了创建外观类,laravel 仅提供名称“db”

framework/src/Illuminate/Support/Facades/DB.php

class DB extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'db';
    }
}

我看了更深,发现这个方法使用了提供的名称

framework/src/Illuminate/Support/Facades/Facade.php

protected static function resolveFacadeInstance($name)
{
    if (is_object($name)) {
        return $name;
    }
    if (isset(static::$resolvedInstance[$name])) {
        return static::$resolvedInstance[$name];
    }
    return static::$resolvedInstance[$name] = static::$app[$name];
}

我理解第一个和第二个 If 语句。

但我在理解这一点上有问题:

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

据我了解,$appFacade 类的受保护属性,其中包含 \Illuminate\Contracts\Foundation\Application 类的实例。

/**
     * The application instance being facaded.
     *
     * @var \Illuminate\Contracts\Foundation\Application
     */
    protected static $app;

我的两个问题:

如果 Application 类不扩展 ArrayObject 类,如何将对象用作数组(static::$app[$name])?

laravel 如何通过只提供一个短名称“db”来理解要调用哪个类?

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    点击 Laravel 源码,我找到了这个。如您所见,ApplicationContract(您问题中的private static $app)由Application 实现。这又是从Container 派生的,它实现了PHP 核心ArrayAccess 接口。仔细实现整个链最终使Applicatin 可以像数组一样访问。

    事实证明它归结为良好的 ole' 面向对象编程 :)

    // Illuminate/Foundation/Application.php
    class Application extends Container implements ApplicationContract, HttpKernelInterface
                              ^^^^^^^^^            ^-> the private static $app in your question.
    
    // Illuminate/Container/Container.php
    class Container implements ArrayAccess, ContainerContract
                               ^^^^^^^^^^^
    
    // PHP core ArrayAccess documentation
    /**
     * Interface to provide accessing objects as arrays.
     * @link http://php.net/manual/en/class.arrayaccess.php
     */
    interface ArrayAccess {
    

    【讨论】:

    • 不是每个人都能深入了解 Laravel 内部结构并知道 Container 类的用途,或者 ArrayAccess 如何用于修改类的行为。您应该解释它们的作用以及它如何解决问题。
    • 哎呀.. 是吗?这实际上只是 OOP 基础知识,例如实现接口和继承类。 Application 派生自实现 ArrayAccessContainer。我也不知道 Container 实际做了什么以及 ArrayAccess 是如何实现的,但是 OOP 和文档告诉我这就是 Application 可以作为对象访问的方式。不过我会更新一些解释。
    • 我理解你。谢谢。我的错误,我查看了 Contracts 目录,这就是我没有找到它的原因
    • 没问题。不过很酷的问题!甚至不知道有像ArrayAccess 这样的东西所以我也学到了一些东西:)
    • 赞成。 Container 类用于在整个应用程序中解析对象实例。 Laravel 本身使用一些巧妙的反射来猜测如何通过其IoC Container 实例化一个没有服务提供者的对象。 ArrayAccess 提供了将对象实例从容器中拉出所需的契约,而无需调用 $this->app->make()offsetGet
    【解决方案2】:

    你可以看看这个,php手册并使用ArrayAccess接口:

    http://php.net/manual/en/class.arrayaccess.php

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-07
      • 1970-01-01
      • 2018-04-29
      • 1970-01-01
      • 2019-12-11
      • 2020-12-09
      相关资源
      最近更新 更多