3

私は単純な URL ビュー ヘルパーを作成し、それを拡張Zend\View\Helper\Urlして に添付しましたViewHelperManager

MyNamespace\View\Helper\Url

namespace MyNamespace\View\Helper;

use Zend\View\Helper\Url as ZendUrl;

class Url extends ZendUrl {
    
    public function __invoke($name = null, array $params = array(), $options = array(), $reuseMatchedParams = false) {
        $link = parent::__invoke($name, $params, $options, $reuseMatchedParams);
        ...
        return $link;
    }
    
}

Application\Module

namespace Application;

use ...

class Module {
    
    public function onBootstrap(MvcEvent $mvcEvent) {
        $application = $mvcEvent->getApplication();
        $serviceManager = $application->getServiceManager();
        $viewHelperManager = $serviceManager->get('ViewHelperManager');
        $viewHelperManager->setInvokableClass('url', 'MyNamespace\View\Helper\Url');
        ...
    }
    
}

ここで、アプリケーションは例外をスローします:

致命的なエラー: /var/www/foo/bar/vendor/zendframework/zendframework/library/Zend/View/Helper/Url.php で、「RouteStackInterface インスタンスが提供されていません」というメッセージを含む例外「Zend\View\Exception\RuntimeException」がキャッチされない76行目

Zend\View\Exception\RuntimeException: No RouteStackInterface インスタンスが /var/www/foo/bar/vendor/zendframework/zendframework/library/Zend/View/Helper/Url.php の 76 行目に提供されていません

Url両方のクラスをデバッグしました。WennMyNamespace\View\Helper\Urlが使用され、メソッドZend\View\Helper\Url#setRouter(...)が呼び出されず、ルーターが設定されていません。理由がわからない...

それを機能させる方法は?

4

4 に答える 4

1

これはテストされていないため、機能するかどうかはわかりません。推測しているだけです:

交換:

$viewHelperManager->setInvokableClass('url', 'MyNamespace\View\Helper\Url');

と:

$viewHelperManager->setFactory('url', function ($sm) use($serviceLocator) {
    $helper = new \MyNamespace\View\Helper\Url;
    $router = Console::isConsole() ? 'HttpRouter' : 'Router';
    $helper->setRouter($serviceLocator->get($router));

    $match = $serviceLocator->get('application')
    ->getMvcEvent()
    ->getRouteMatch();

    if ($match instanceof RouteMatch) {
        $helper->setRouteMatch($match);
    }

    return $helper;
});
于 2013-04-13T13:57:57.043 に答える
1

この質問はかなり古いものですが、ここに構成ベースのオーバーライドを追加するだけでなく、HelperPluginManager次のように登録されたファクトリを使用する価値があると考えました。

内部module.config.php:

'view_helpers' => array(
    'factories'=> array(
        'url' => 'Application\View\Helper\UrlFactory',
    )
),

ビュー ヘルパー プラグイン ファクトリ自体:

<?php

namespace Application\View\Helper;

use Zend\Console\Console;
use Zend\Mvc\Router\RouteMatch;
use Zend\Mvc\Router\RouteStackInterface;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\View\Helper\Url as BaseUrlHelper;
use Zend\View\HelperPluginManager;

class UrlFactory implements FactoryInterface
{
    /**
     * Create service
     *
     * @param ServiceLocatorInterface $helperPluginManager
     * @return mixed
     */
    public function createService(ServiceLocatorInterface $helperPluginManager)
    {
        /**
         * @var $helperPluginManager HelperPluginManager
         * @var $router RouteStackInterface
         */
        $serviceLocator = $helperPluginManager->getServiceLocator();
        $helper = new Url();

        $router = Console::isConsole() ? 'HttpRouter' : 'Router';
        $router = $serviceLocator->get($router);
        $helper->setRouter($router);

        $match = $serviceLocator->get('application')
            ->getMvcEvent()
            ->getRouteMatch()
        ;

        if ($match instanceof RouteMatch) {
            $helper->setRouteMatch($match);
        }

        return $helper;
    }
}

ここでの秘訣は、このファクトリでは、HelperPluginManagerサービス ロケーターのみを受け取ることです。他のサービスにアクセスするには、最初にグローバル サービス ロケーターをフェッチする必要があります (これは、use他のすべてのソリューションでクロージャーの外側からグローバル サービス ロケーターを ing することによって行われます)。

于 2016-02-06T10:33:45.693 に答える