3
votes

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

2

2 Answers

4
votes

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 {
0
votes

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

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