How can I replace the PhpRenderer in a ZF2 application

核能气质少年 提交于 2019-12-22 18:11:42

问题


I have extended the PhpRenderer class in my ZF2 application like this:

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

}

I don't want to add a new rendering strategy, I just extend the PhpRenderer to add some @method phpdoc for my viewhelpers.

How can I replace the standard PhpRenderer with my extended PhpRenderer so it will be used to render my viewscripts?


回答1:


The php renderer is a service inside the service manager. You can override this service directly or do it via the view manager (which instantiates and configures the renderer).

Override the service

In your module you define an onBootstrap() method. The "old" php renderer is already registered, you have to redefine it.

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);
}

Override the view manager

There is an alternative where you can redefine the view manager where the php renderer is instantiated. You have to redefine the view manager's factory for this:

In your application.config.php (note it is the application config, as the module config will not work here!)

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

Then create your 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();
    }
}

And then you can finally update the factory of the php renderer itself:

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;
    }
}

Conclusion

The first method instantiates the normal php renderer already, so you instantiate two of them and replace the default with your own.

An alternative is to circumvent the instantiation of the default Zend's php renderer, but you have to do this inside the view manager class. The problem here is you have to redefine the factory for the view manager as well. This sounds as a detour, but it is the only way to get this done.




回答2:


If all your custom class contains is @method declarations then you don't need to replace the php renderer class. Just make sure to use the @var docblock and your IDE will know what to do:

Document the type for the $this variable in your view files:

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

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

Document individual variables or properties for view helpers, classes, etc:

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

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


来源:https://stackoverflow.com/questions/20194053/how-can-i-replace-the-phprenderer-in-a-zf2-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!