Zend framework 2: помощник по поиску сервисов

Я пытаюсь получить доступ к локатору служб в помощнике просмотра, чтобы получить доступ к своей конфигурации. Я использую этот помощник представления для рекурсивной функции, поэтому я не знаю, где объявить локатор службы.

namespace Application\View\Helper;

use Zend\View\Helper\AbstractHelper;
use CatMgt\Model\CategoryTable as RecursiveTable;

class CategoryRecursiveViewHelper extends AbstractHelper
{
    protected $table;

    public function __construct(RecursiveTable $rec)
    {
        $this->table = $rec; 
    }

    public function __invoke($project_id, $id, $user_themes_forbidden, $level, $d, $role_level)
    {

       $config = $serviceLocator->getServiceLocator()->get('config');

       //So i can access $config['templates']

       $this->__invoke($val->project_id, $id, $user_themes_forbidden, $level, $d, $role_level);

    }

}

Я попробовал решение, приведенное здесь ссылка

Но не помогло, нормально ли так делать?

namespace Application\View\Helper;

use Zend\View\Helper\AbstractHelper;
use CatMgt\Model\CategoryTable as RecursiveTable;
use Zend\View\HelperPluginManager as ServiceManager;

class CategoryRecursiveViewHelper extends AbstractHelper
{
    protected $table;
    protected $serviceManager;

    public function __construct(RecursiveTable $rec, ServiceManager $serviceManager)
    {
        $this->table = $rec; 
        $this->serviceManager = $serviceManager;
    }

    public function __invoke($project_id, $id, $user_themes_forbidden, $level, $d, $role_level)
    {

       $config = $this->serviceManager->getServiceLocator()->get('config');

       //So i can access $config['templates']

       $this->__invoke($val->project_id, $id, $user_themes_forbidden, $level, $d, $role_level);

    }

}

person Brieuc    schedule 08.05.2014    source источник


Ответы (1)


Прежде всего, ваш ViewHelper - это бесконечный цикл, и ваше приложение вот так вылетит. Вы вызываете __invoke в __invoke - это просто не сработает.

Регистрация ViewHelper с зависимостями

Во-первых, вы должны написать свой ViewHelper как:

class FooBarHelper extends AbstractHelper
{
    protected $foo;
    protected $bar;

    public function __construct(Foo $foo, Bar $bar)
    {
        $this->foo = $foo;
        $this->bar = $bar;
    }

    public function __invoke($args)
    {
        return $this->foo(
            $this->bar($args['something'])
        );
    }
}

Далее идет регистрация ViewHelper. Поскольку для этого требуется зависимость, вы должны использовать factory в качестве цели.

// module.config.php
'view_helpers' => [
    'factories' => [
        'foobar' => 'My\Something\FooBarHelperFactory'
    ]
]

Теперь целью является factory -класс, который нам еще предстоит написать. Итак, вперед:

class FooBarHelperFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $sl)
    {
        // $sl is instanceof ViewHelperManager, we need the real SL though
        $rsl = $sl->getServiceLocator();
        $foo = $rsl->get('foo');
        $bar = $rsl->get('bar');

        return new FooBarHelper($foo, $bar);
    }
}

Теперь вы можете использовать свой ViewHelper через $this->foobar($args) в любом из ваших файлов просмотра.

Никогда не используйте ServiceLocator как зависимость

Всякий раз, когда вы полагаетесь на ServiceManager как на зависимость, вы впадаете в плохой дизайн. У ваших классов будут зависимости неизвестного типа, и они будут скрыты. Когда вашему классу нужны внешние данные, сделайте их доступными напрямую через __construct() и не скрывайте зависимости, вставляя ServiceManager.

person Sam    schedule 08.05.2014
comment
Хорошо, спасибо, мне это более понятно, я всегда путала, как использовать serviceLocator. - person Brieuc; 08.05.2014
comment
// $sl is instanceof ViewHelperManager, we need the real SL though вы только что сэкономили мне часы исследования, спасибо !!. К тому же я стал меньше доверять команде дизайнеров ZF. Вероятно, это следует разместить в / r / lol_php - person Christopher Francisco; 12.04.2017
comment
@ChristopherFrancisco Решение о дизайне имело смысл, но было слишком сложно для понимания большинства людей. К счастью, прямо сейчас у нас есть работа с контейнером PSR;) - person Sam; 12.04.2017
comment
Потрясающие! Следуйте инструкциям, и это работает! Действительно хороший пост! - person Ron; 18.12.2018