Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How laravel uses object as an array in Facade class

Tags:

php

laravel

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'?

like image 811
John Kent Avatar asked Oct 22 '25 23:10

John Kent


1 Answers

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 {
like image 64
Loek Avatar answered Oct 25 '25 13:10

Loek