Звонок в View::make
есть, в Ларавеле говорят по телефону View
фасад. Фасады обеспечивают глобальный статический доступ к сервису в контейнере обслуживания. Шаг 1 является LookUp Фактический класс View
указывает на
#File: app/config/app.php
'aliases' => array(
'View' => 'Illuminate\Support\Facades\View',
)
Это означает, что View
является совмещенным к классу Illuminate\Support\Facades\View
. Если вы посмотрите на источник Illuminate\Support\Facades\View
#File: vendor/laravel/framework/src/Illuminate/Support/Facades/View.php
class View extends Facade {
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor() { return 'view'; }
}
Вы можете увидеть аксессор фасад сервис view
. Это означает, что вызов
View::make...
(более или менее), что эквивалентно вызову к
$app = app();
$app['view']->make(...
То есть, фасад обеспечивает доступ к view
службы в контейнере службы. Чтобы заменить другой класс, все, что вам нужно сделать, это связать другой объект в качестве службы view
. Laravel предоставляет метод extend
для этого.
App::extend('view', function(){
$app = app();
// Next we need to grab the engine resolver instance that will be used by the
// environment. The resolver will be used by an environment to get each of
// the various engine implementations such as plain PHP or Blade engine.
$resolver = $app['view.engine.resolver'];
$finder = $app['view.finder'];
$env = new \MyProject\Extensions\View($resolver, $finder, $app['events']);
// We will also set the container instance on this view environment since the
// view composers may be classes registered in the container, which allows
// for great testable, flexible composers for the application developer.
$env->setContainer($app);
$env->share('app', $app);
return $env;
});
Обратите внимание, что это больше, чем просто создание объекта. Нам нужно создать экземпляр так же, как была создана и привязана к исходной службе представления (обычно с bind
или bindShared
). Вы можете найти этот код здесь
#File: vendor\laravel\framework\src\Illuminate\View\ViewServiceProvider.php
public function registerFactory()
{
$this->app->bindShared('view', function($app)
{
// Next we need to grab the engine resolver instance that will be used by the
// environment. The resolver will be used by an environment to get each of
// the various engine implementations such as plain PHP or Blade engine.
$resolver = $app['view.engine.resolver'];
$finder = $app['view.finder'];
$env = new Factory($resolver, $finder, $app['events']);
// We will also set the container instance on this view environment since the
// view composers may be classes registered in the container, which allows
// for great testable, flexible composers for the application developer.
$env->setContainer($app);
$env->share('app', $app);
return $env;
});
}
Вы можете проверить, если ваш связывание работал с кодом, как этот
var_dump(get_class(app()['view']));
Вы должны видеть ваше имя класса. Как только вы уверены, что привязка «взята», вы можете переопределить все методы, которые вы хотите.
Большое вам спасибо, сейчас у меня все работает. В качестве окончательного вопроса: хорошо ли использовать код App :: extend() в файле /start/global.php? Я не был уверен, куда его поместить, и я думаю, что официальная документация указывает на это местоположение ... – user132169
@ user132169 Там должно быть хорошо, хотя я думаю, что 'start/global.php' уходит в Laravel 5.0 (если вы не используете устаревшего поставщика услуг) –