2014-09-23 7 views
3

Я хотел бы переопределить метод по умолчанию View::make() в Laravel, который может быть использован для возврата пользователю вида-ответа.Как переопределить View :: make() в Laravel 4?

(я думаю) я уже понял, что этот метод хранится внутри Illuminate\View\Factory.php, и я читал о IoC контейнера, пытаясь заставить его работать, используя somesimilartutorials, но он просто не будет работать ,

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

Спасибо!

ответ

11

Звонок в 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'])); 

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

+0

Большое вам спасибо, сейчас у меня все работает. В качестве окончательного вопроса: хорошо ли использовать код App :: extend() в файле /start/global.php? Я не был уверен, куда его поместить, и я думаю, что официальная документация указывает на это местоположение ... – user132169

+0

@ user132169 Там должно быть хорошо, хотя я думаю, что 'start/global.php' уходит в Laravel 5.0 (если вы не используете устаревшего поставщика услуг) –

Смежные вопросы