Я как бы смотрю на то, что происходит на фасадах 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 :: get () – это вызванный Фасад
static :: $ app [$ name] решит, что я думаю Application ['files'] или Application-> файлы, которые, в свою очередь, вызывают Application -> __ get ('files'), поскольку в классе Application отсутствует свойство файлов .
Как вернуть класс FileSystem, если это только содержимое этого метода?
public function __get($key) { return $this[$key]; }
Я постараюсь кратко описать:
Итак, вы уже знаете, что метод 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
может быть (доступно) установлено / получено с использованием нотации массива.
Я попытался дать вам представление, но вы должны заглянуть в код, шаг за шагом, вы не получите его только чтение / отслеживание кода один раз.