Мне нужно глубоко понять ларавел. Я должен все объяснить своей команде разработчиков, так как мы начинаем использовать laravel.
Пожалуйста, исправьте это, если это неверно: при запуске laravel из-за увеличения производительности он разделяет поставщика услуг на «нетерпеливые» и «отложенные», затем регистрирует всех «нетерпеливых» поставщиков, но не «отложен».
Мой вопрос: каждый раз, когда мы используем отложенные услуги, например:
$validator = Validator::make( //.. );
Как laravel загружает и регистрирует этот класс / услуги? Я просто нашел эту связанную строку 70 в классе Illuminate\Foundation\ProviderRepository
$app->setDeferredServices($manifest['deferred']);
Но потом я застрял. Извините за плохой английский, надеюсь, вы все понимаете. Благодарю.
Я тоже хотел знать ответ на этот вопрос, но вместо этого решил искать себя.
Если вы перейдете в app/storage/meta
появится services.json
котором перечислены eager
и deferred
классы. Таким образом, мы не загружаем все классы для каждого запроса, поскольку нам может понадобиться класс Form
если мы создаем API.
Класс ProviderRepository
сканирует всех поставщиков, перечисленных в app/config/app.php
и создает поставщиков для каждого из них (это не фактические библиотеки).
Эти поставщики, например CacheServiceProvider
в Illuminate/Cache
имеют переменную, называемую defer
которая определяет, будет ли библиотека загружена отложенной до тех пор, пока она не понадобится.
Вот цитата из ProviderRepository
При перекомпиляции манифеста службы мы будем прокручивать каждого из поставщиков и проверять, является ли он отсроченным поставщиком или нет. Если это так, мы добавим предоставленные им услуги в манифест и обратите внимание на поставщика.
Для CacheServiceProvider
это значение равно true
.
Поэтому давайте скажем, Validator::make()
вызывается Validator::make()
вот что я собрал; Каждый Facade
такой как фасад Validator
расширяет базовый класс Facade
в Illuminate\Support\Facades\Facade
.
У этого есть волшебный метод __callStatic($method, $args)
который вполне объяснителен, основным моментом этого метода является
$instance = static::resolveFacadeInstance(static::getFacadeAccessor());
Аксессор фасада в этом случае возвращает строку фактического класса, который выполняет проверку ( Illuminate\Validation\Validator
):
protected static function getFacadeAccessor() { return 'validator'; }
Основной метод resolveFacadeInstance
проверяет, является ли возвращаемый объект доступа объектом. Если он просто возвращает это обратно, поскольку это, вероятно, настраиваемый пакет Laravel.
Вторая часть этого метода проверяет, была ли она уже разрешена, если она возвращает это. Заключительная часть:
return static::$resolvedInstance[$name] = static::$app[$name];
Вызывает Illuminate\Foundation\Application
(который расширяет класс Illuminate\Container\Container
) через интерфейс доступа к массиву, расположенный в упомянутом выше родительском классе.
Таким образом, static::$app[$name]
вызывает:
public function offsetGet($key) { return $this->make($key); }
Это расположено в классе Container
Это приводит нас к методу make()
в классе Application
:
public function make($abstract, $parameters = array()) { if (isset($this->deferredServices[$abstract])) { $this->loadDeferredProvider($abstract); } return parent::make($abstract, $parameters); }
Я позволю вам углубиться в метод parent::make()
как это начнет становиться очень длинным, но в его нынешнем виде он загружает отложенного провайдера и создает его через loadDeferredProvider()
public function loadDeferredProviders() { // We will simply spin through each of the deferred providers and register each // one and boot them if the application has booted. This should make each of // the remaining services available to this application for immediate use. foreach (array_unique($this->deferredServices) as $provider) { $this->register($instance = new $provider($this)); if ($this->booted) $instance->boot(); } $this->deferredServices = array(); }
Комментарии в блоке кода должны объяснить остальную часть того, что происходит.
Отсюда последняя часть __callStatic($method, $args)
запускает реальный метод, называемый Validator::make()
.
public static function __callStatic($method, $args) { $instance = static::resolveFacadeInstance(static::getFacadeAccessor()); switch (count($args)) { case 0: return $instance->$method(); case 1: return $instance->$method($args[0]); case 2: return $instance->$method($args[0], $args[1]); case 3: return $instance->$method($args[0], $args[1], $args[2]); case 4: return $instance->$method($args[0], $args[1], $args[2], $args[3]); default: return call_user_func_array(array($instance, $method), $args); } }
Таким образом, фасад вызывает нестатический метод validate()
Illuminate\Validation\Validator
validate()
.
Я уверен, что это точно для 4.0, но, пожалуйста, поправьте меня, если будут ошибки.