如何在Laravel 4中覆盖View :: make()?

Jes*_*ssy 3 php class core extend laravel

我想覆盖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
    }

}
Run Code Online (Sandbox Code Playgroud)

MyProject文件夹自动加载与作曲家.但是,Factory每当调用View(特别是View::make())静态方法时,我都不知道如何使用该类的"修改"版本.一些帮助会很棒!

谢谢!

Ala*_*orm 11

调用View::make,在Laravel说话,先呼叫View门面.Facade提供对服务容器中服务的全局静态访问.第1步是查找实际的类View

#File: app/config/app.php
'aliases' => array(
    'View'            => 'Illuminate\Support\Facades\View',
)
Run Code Online (Sandbox Code Playgroud)

这意味着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'; }

}
Run Code Online (Sandbox Code Playgroud)

您可以看到外观服务访问器view.这意味着打电话给

View::make...
Run Code Online (Sandbox Code Playgroud)

(或多或少)等同于对...的调用

$app = app();
$app['view']->make(...
Run Code Online (Sandbox Code Playgroud)

也就是说,Facade提供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;                
});
Run Code Online (Sandbox Code Playgroud)

请注意,这不仅仅是实例化一个对象.我们需要实例化它,就像原始视图服务被实例化和绑定一样(通常使用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;
    });
}
Run Code Online (Sandbox Code Playgroud)

您可以测试绑定是否与此类代码一起使用

var_dump(get_class(app()['view']));
Run Code Online (Sandbox Code Playgroud)

你应该看到你的班级名称.一旦你确定绑定已经"采取",你可以自由地重新定义你想要的任何方法.