如何在ZF2应用程序中替换PhpRenderer

时间:2013-11-25 13:14:33

标签: php zend-framework2

我已经在我的ZF2应用程序中扩展了PhpRenderer类,如下所示:

namespace MyLib\View\Renderer;
class PhpRenderer extends \Zend\View\Renderer\PhpRenderer
{

}

我不想添加新的渲染策略,我只是将PhpRenderer扩展为add some @method phpdoc for my viewhelpers

如何用扩展的PhpRenderer替换标准的PhpRenderer,以便它用于渲染我的视图?

2 个答案:

答案 0 :(得分:1)

php渲染器是服务管理器内的服务。您可以直接覆盖此服务,也可以通过视图管理器(实例化和配置渲染器)来执行此操作。

覆盖服务

在您的模块中,您可以定义onBootstrap()方法。 “旧的”php渲染器已经注册,你必须重新定义它。

public function onBootstrap($e)
{
    $app = $e->getApplication();
    $sm  = $app->getServiceManager();

    $old = $sm->get('ViewRenderer');
    $new = new MyCustomViewRenderer;

    $new->setHelperPluginManager($old->getHelperPluginManager());
    $new->setResolver($old->getResolver());

    $sm->setAllowOverride(true);
    $sm->setService('ViewRenderer', $new);
    $sm->setAllowOverride(false);
}

覆盖视图管理器

还有一种方法可以重新定义实例化php渲染器的视图管理器。您必须为此重新定义视图管理器的工厂:

在你的application.config.php中(注意它是 application config,因为模块配置在这里不起作用!)

service_manager => array(
    'factories' => array(
        'HttpViewManager' => 'MyModule\Service\HttpViewManagerFactory',
    ),
);

然后创建MyModule \ Service \ HttpViewManagerFactory:

use MyModule\View\Http\ViewManager as HttpViewManager;

class HttpViewManagerFactory implements FactoryInterface
{
    /**
     * Create and return a view manager for the HTTP environment
     *
     * @param  ServiceLocatorInterface $serviceLocator
     * @return HttpViewManager
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        return new HttpViewManager();
    }
}

然后你最终可以更新php渲染器本身的工厂:

use Zend\Mvc\View\Http\ViewManager as BaseViewManager;

class ViewManager extends BaseViewManager
{
    public function getRenderer()
    {
        if ($this->renderer) {
            return $this->renderer;
        }

        $this->renderer = new MyCustomViewPhpRenderer;
        $this->renderer->setHelperPluginManager($this->getHelperManager());
        $this->renderer->setResolver($this->getResolver());

        $model       = $this->getViewModel();
        $modelHelper = $this->renderer->plugin('view_model');
        $modelHelper->setRoot($model);

        $this->services->setService('ViewRenderer', $this->renderer);
        $this->services->setAlias('Zend\View\Renderer\PhpRenderer', 'ViewRenderer');
        $this->services->setAlias('Zend\View\Renderer\RendererInterface', 'ViewRenderer');

        return $this->renderer;
    }
}

<强>结论

第一种方法已经实例化了普通的php渲染器,所以你实例化其中两个并用你自己的默认值替换默认值。

另一种方法是绕过默认Zend的php渲染器的实例化,但你必须在视图管理器类中执行此操作。这里的问题是你必须重新定义视图管理器的工厂。这听起来像绕道而行,但这是完成这项任务的唯一方法。

答案 1 :(得分:1)

如果您的所有自定义类都包含@method声明,那么您不需要替换php渲染器类。只需确保使用@var docblock,您的IDE就会知道该怎么做:

记录视图文件中$this变量的类型:

<!-- in a view file -->
<?php /* @var $this MyLib\View\Renderer\PhpRenderer */ ?>

<?= $this->myCustomViewHelper() ?>

记录视图助手,类等的各个变量或属性:

class SomeHelper extends AbstractHelper
{
    /** @var \MyLib\View\Renderer\PhpRenderer */
    protected $view;

    public function __invoke()
    {
        $this->view->myCustomViewHelper();
    }
}