John Kent
John Kent

Reputation: 386

How laravel uses object as an array in Facade class

I've noted that for creating a facade class, laravel provides only name "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';
    }
}

I looked deeper and figured out that this method uses the provided name

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];
}

I understand first and second If statements.

But I have problems with understanding this:

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

As I understood that $app is a protected property of Facade class which contains an instance of \Illuminate\Contracts\Foundation\Application class.

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

My two questions:

How is it possible to use an object as an array(static::$app[$name]) if Application class doesn't extends ArrayObject class?

How laravel understands which class to call with providing only a short name 'db'?

Upvotes: 4

Views: 1078

Answers (2)

Loek
Loek

Reputation: 4135

Clicking through the Laravel source, I found this. As you can see, ApplicationContract (the private static $app from your question) is implemented by Application. This is in turn derived from Container, which implements the PHP core ArrayAccess interface. Carefully implementing this whole chain eventually makes Applicatin accessible like an array.

Turns out it boils down to good ole' object oriented programming :)

// 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 {

Upvotes: 5

shubiao-yao
shubiao-yao

Reputation: 36

You can look this, php manual and use ArrayAccess interface:

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

Upvotes: 0

Related Questions