Как переопределить View :: make () в Laravel 4?

Я хотел бы переопределить значение по умолчанию 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()) называется. Некоторая помощь будет отличной!

Спасибо!

3

Решение

Призыв к 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']));

Вы должны увидеть ваше имя класса. Если вы уверены, что привязка «взята», вы можете переопределять любые методы, которые вам нужны.

11

Другие решения

Других решений пока нет …