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

框架/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';
    }
}

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

框架/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 类的 protected 属性,其中包含 \Illuminate\Contracts\Foundation\Application 类的一个实例。
/**
     * The application instance being facaded.
     *
     * @var \Illuminate\Contracts\Foundation\Application
     */
    protected static $app;

我的两个问题:

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

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

最佳答案

单击 Laravel 源,我找到了这个。如您所见, ApplicationContract (您问题中的 private static $app)由 Application 实现。这反过来又源自 Container ,它实现了 PHP 核心 ArrayAccess 接口(interface)。仔细实现整个链最终会使 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 {

关于php - laravel 如何在 Facade 类中使用对象作为数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50530710/

10-11 17:22
查看更多