Я хотел бы переопределить значение по умолчанию View::make()
метод в Laravel, который можно использовать для возврата пользователю ответа на просмотр.
(Я думаю) я уже понял, что этот метод хранится внутри Illuminate\View\Factory.php
, и я читал о контейнере IoC, пытаясь заставить его работать с помощью немного аналогичный учебные пособия, но это просто не сработает.
Я уже создал файл App\Lib\MyProject\Extensions\View\Factory.php
, содержащий следующий код:
<?php namespace MyProject\Extensions\View;
use Illuminate\View\Factory as OldFactory;
class Factory extends OldFactory {
public static function make() {
// My own implementation which should override the default
}
}
где MyProject
папка автоматически загружается с помощью Composer. Но я не знаю, как использовать эту «модифицированную» версию Factory
класс всякий раз, когда статический метод View
(особенно View::make()
) называется. Некоторая помощь будет отличной!
Спасибо!
Призыв к View::make
это, по словам Ларавела, призыв к View
фасад. Фасады обеспечивают глобальный статический доступ к услуге в контейнере службы. Шаг 1 — поиск фактического класса 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']));
Вы должны увидеть ваше имя класса. Если вы уверены, что привязка «взята», вы можете переопределять любые методы, которые вам нужны.
Других решений пока нет …