Laravel 4: Как решены Фасады?

Я как бы смотрю на то, что происходит на фасадах Laravel 4 под капотом.

Давайте возьмем этот Фасад в качестве примера:

File::get(someArgs); 

Если я не ошибаюсь, шаг за шагом (упрощенным) вызовом будет:

 //static method invocation which are all extended from Facade class File::__callStatic(get, someArgs) //returns an instance of FileSystem File::resolveFacedeInstance('files') FileSystem->get(someArgs) 

То, о чем я смущаюсь, находится в приведенной ниже строке метода File :: resolveFacadeInstance () ниже:

 protected static function resolveFacadeInstance($name) { if (is_object($name)) return $name; if (isset(static::$resolvedInstance[$name])) { return static::$resolvedInstance[$name]; } /** * The line that i'm confused about */ return static::$resolvedInstance[$name] = static::$app[$name]; } 

Мои вопросы:

  • Как File :: $ app даже инициализируется или назначается значение внутри класса Facade
  • Если File :: get () – это вызванный Фасад

    static :: $ app [$ name] решит, что я думаю Application ['files'] или Application-> файлы, которые, в свою очередь, вызывают Application -> __ get ('files'), поскольку в классе Application отсутствует свойство файлов .

    Как вернуть класс FileSystem, если это только содержимое этого метода?

     public function __get($key) { return $this[$key]; } 

Solutions Collecting From Web of "Laravel 4: Как решены Фасады?"

Я постараюсь кратко описать:

Итак, вы уже знаете, что метод resolveFacadeInstance вызывается с помощью метода resolveFacadeInstance класса Facade и Facade компонента (ie File extends Facade) расширяет этот класс Facade .

Во время процесса загрузки фреймворка из public/index.php следующая строка запускает выполнение файла bootstrap/start.php

 $app = require_once __DIR__.'/../bootstrap/start.php'; 

Итак, в этом файле ( bootstrap/start.php ) вы можете увидеть какой-то код, например

 // the first line, initiate the application $app = new Illuminate\Foundation\Application; // ... // ... // notice this line require $framework.'/Illuminate/Foundation/start.php'; // ... // last line return $app; 

В этом фрагменте кода require $framework.'/Illuminate/Foundation/start.php'; line запускает исполнение файла Foundation/start.php и в этом файле вы можете увидеть что-то вроде этого

 // ... Facade::clearResolvedInstances(); // Notice this line Facade::setFacadeApplication($app); 

Эта строка (заданная выше) устанавливает application instanse в свойство $app в классе Facade

 // support/Facades/Facade.php public static function setFacadeApplication($app) { static::$app = $app; } 

Затем в файле Foundation/start.php внизу вы можете увидеть что-то вроде этого

 /* |-------------------------------------------------------------------------- | Register The Core Service Providers |-------------------------------------------------------------------------- | | The Illuminate core service providers register all of the core pieces | of the Illuminate framework including session, caching, encryption | and more. It's simply a convenient wrapper for the registration. | */ $providers = $config['providers']; $app->getProviderRepository()->load($app, $providers); $app->boot(); 

В этом фрагменте кода, приведенном выше, все основные компоненты, зарегистрированные платформой, и, как вы знаете, каждый компонент имеет класс поставщика услуг (например, FilesystemServiceProvider ), а в каждом классе поставщика услуг есть register методов, который (для FilesystemServiceProvider )

 /** * Register the service provider. * * @return void */ public function register() { $this->app['files'] = $this->app->share(function() { return new Filesystem; }); } 

Ну, в этом случае параметр $this->app['files'] ( return new Filesystem ) анонимную функцию, которая возвращает filesystem при ее выполнении

 $this->app['files'] = $this->app->share(function() { return new Filesystem; }); 

в $app['files'] поэтому, когда вы вызываете File::get() , он, наконец, вызывает анонимную функцию, и в этом случае следующая строка

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

Вызывает функцию для static::$app['file']; и эта функция возвращает экземпляр, но перед возвратом он сохраняет экземпляр в переменной $resolvedInstance , поэтому в следующий раз он может вернуть экземпляр из переменной без повторного вызова анонимной функции. Таким образом, это выглядит так: static::$resolvedInstance[$name] = static::$app[$name]; вызывает анонимную функцию, которая возвращает экземпляр, и эта функция была зарегистрирована ранее, когда app было запущено с помощью процесса загрузки.

Важный :

Application расширяет Container и Container расширяет класс ArrayAccess, и поэтому свойство объекта $app может быть (доступно) установлено / получено с использованием нотации массива.

Я попытался дать вам представление, но вы должны заглянуть в код, шаг за шагом, вы не получите его только чтение / отслеживание кода один раз.