ZF2 - получить имя контроллера в макете/представлении

Я знаю, что с ZF1 вы получите имя модуля/контроллера, используя настраиваемые помощники представления, которые получат объект singleton frontController и получат там имя.

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

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

Причина, по которой мне нужно имя контроллера, состоит в том, чтобы добавить его в тело в качестве класса для определенного стиля контроллера.

Спасибо, Дом


person Intellix    schedule 12.01.2012    source источник


Ответы (9)


ZF2 отсутствует, как и скелет. Это добавление поверх скелета, поэтому это должен быть ваш лучший пример:

Внутри модуля.php

public function onBootstrap($e)
{
    $e->getApplication()->getServiceManager()->get('translator');
    $e->getApplication()->getServiceManager()->get('viewhelpermanager')->setFactory('controllerName', function($sm) use ($e) {
        $viewHelper = new View\Helper\ControllerName($e->getRouteMatch());
        return $viewHelper;
    });

    $eventManager        = $e->getApplication()->getEventManager();
    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);
}

Фактический ViewHelper:

// Application/View/Helper/ControllerName.php

namespace Application\View\Helper;

use Zend\View\Helper\AbstractHelper;

class ControllerName extends AbstractHelper
{

protected $routeMatch;

    public function __construct($routeMatch)
    {
        $this->routeMatch = $routeMatch;
    }

    public function __invoke()
    {
        if ($this->routeMatch) {
            $controller = $this->routeMatch->getParam('controller', 'index');
            return $controller;
        }
    }
}

Внутри любого из ваших представлений/макетов

echo $this->controllerName()
person Intellix    schedule 25.10.2012
comment
Кроме того, если вы получаете ошибки при вызове getParam() для не-объекта, возможно, стоит проверить, вызывается ли ресурс и существует ли он... например, значок значка. Если бы ZF2 вызывался и загружался без каких-либо параметров, когда favicon вызывался и не существовал, поэтому это жаловалось/регистрировало ошибку и делало каждый запрос очень медленным. - person Intellix; 19.01.2013
comment
Привет, Доминик Ватсон, я получил ошибку вместо страницы 404. Могу ли я узнать, как проверить, что ресурс вызывается или существует? Я новичок в ZF2, пожалуйста, помогите - person Kathiravan; 01.07.2013
comment
Я добавил if ($this-›routeMatch) в приведенный выше код, чтобы проверить, что он существует, поэтому вы должны получить 404, а не ошибку (поскольку нет routeMatch для отсутствующего значка или чего-то подобного) - person Intellix; 01.07.2013
comment
Неустранимая ошибка: класс «Application\View\Helper\ControllerName» не найден в C:\wamp\www\project\module\Application\Module.php в строке 95... Моя структура каталогов - это модуль ››Application››view› ›Помощник››ControllerName.php....что не так - person user269867; 12.02.2014
comment
Он должен быть в: module››Application››src››Application››View››Helper››ControllerName.php — вы поместили его туда, где находятся ваши фактические представления phtml. - person Intellix; 13.02.2014
comment
Спасибо, это сработало для меня. Могу ли я также получить имя действия? - person Sarang; 22.04.2016

вместо расширения onBootStrap() в Module.php вы можете использовать getViewHelperConfig() (также в Module.php). Фактический помощник не изменился, но вы получаете следующий код для его создания:

public function getViewHelperConfig()
{
   return array(
         'factories' => array(
            'ControllerName' => function ($sm) {
               $match = $sm->getServiceLocator()->get('application')->getMvcEvent()->getRouteMatch();
               $viewHelper = new \Application\View\Helper\ControllerName($match);
               return $viewHelper;
            },
         ),
   );
}
person dstj    schedule 10.12.2012

Короткий код здесь:

$this->getHelperPluginManager()->getServiceLocator()->get('application')->getMvcEvent()->getRouteMatch()->getParam('action', 'index');

$controller = $this->getHelperPluginManager()->getServiceLocator()->get('application')->getMvcEvent()->getRouteMatch()->getParam('controller', 'index');

$controller = array_pop(explode('\', $controller));
person James Labs    schedule 17.04.2014

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

<?php
namespace Application\View\Helper;

use Zend\View\Helper\AbstractHelper;

/**
 * View Helper to return current module, controller & action name.
 */
class CurrentRequest extends AbstractHelper
{
    /**
     * Current Request parameters
     *
     * @access protected
     * @var array
     */
    protected $params;

    /**
     * Current module name.
     *
     * @access protected
     * @var string
     */
    protected $moduleName;

    /**
     * Current controller name.
     *
     * @access protected
     * @var string
     */
    protected $controllerName;

    /**
     * Current action name.
     *
     * @access protected
     * @var string
     */
    protected $actionName;

    /**
     * Current route name.
     *
     * @access protected
     * @var string
     */
    protected $routeName;

    /**
     * Parse request and substitute values in corresponding properties.
     */
    public function __invoke()
    {
        $this->params = $this->initialize();
        return $this;
    }

    /**
     * Initialize and extract parameters from current request.
     *
     * @access protected
     * @return $params array
     */
    protected function initialize()
    {
        $sm = $this->getView()->getHelperPluginManager()->getServiceLocator();
        $router = $sm->get('router');
        $request = $sm->get('request');
        $matchedRoute = $router->match($request);
        $params = $matchedRoute->getParams();
        /**
         * Controller are defined in two patterns.
         * 1. With Namespace
         * 2. Without Namespace.
         * Concatenate Namespace for controller without it.
         */
        $this->controllerName = !strpos($params['controller'], '\\') ?
            $params['__NAMESPACE__'].'\\'.$params['controller'] :
            $params['controller'];
        $this->actionName = $params['action'];
        /**
         * Extract Module name from current controller name.
         * First camel cased character are assumed to be module name.
         */
        $this->moduleName = substr($this->controllerName, 0, strpos($this->controllerName, '\\'));
        $this->routeName = $matchedRoute->getMatchedRouteName();
        return $params;
    }

    /**
     * Return module, controller, action or route name.
     *
     * @access public
     * @return $result string.
     */
    public function get($type)
    {
        $type = strtolower($type);
        $result = false;
        switch ($type) {
            case 'module':
                    $result = $this->moduleName;
                break;
            case 'controller':
                    $result = $this->controllerName;
                break;
            case 'action':
                    $result = $this->actionName;
                break;
            case 'route':
                    $result = $this->routeName;
                break;
        }
        return $result;
    }
}

Чтобы получить доступ к значениям в макете/представлении, вот как я это делаю.

1. $this->currentRequest()->get('module');
2. $this->currentRequest()->get('controller');
3. $this->currentRequest()->get('action');
4. $this->currentRequest()->get('route');

Надеюсь, это поможет кому-то.

person Ibrahim Azhar Armar    schedule 17.01.2015
comment
в $params нет __NAMESPACE__. Какую версию вы используете? - person tasmaniski; 05.10.2015

В zf2 beta4 это сделано так:

public function init(ModuleManager $moduleManager)
{

    $sharedEvents = $moduleManager->events()->getSharedManager();
    $sharedEvents->attach('bootstrap', 'bootstrap', array($this, 'onBootstrap'));
}

public function onBootstrap($e)
{
    $app     = $e->getParam('application');
    // some your code here
    $app->events()->attach('route', array($this, 'onRouteFinish'), -100);
}

public function onRouteFinish($e)
{
     $matches    = $e->getRouteMatch();
     $controller = $matches->getParam('controller');
     var_dump($controller);die();
}
person rdo    schedule 25.05.2012
comment
Пример взят отсюда: - person rdo; 25.05.2012

Для этой цели я создал CurrentRoute View Helper.

Установите его:

composer require tasmaniski/zf2-current-route

Зарегистрируйте модуль в config/application.config.php:

'modules' => array(
    '...',
    'CurrentRoute'
),

Используйте его в любом файле вида/макета:

$this->currentRoute()->getController();  // return current controller name
$this->currentRoute()->getAction();      // return current action name
$this->currentRoute()->getModule();      // return current module name
$this->currentRoute()->getRoute();       // return current route name

Вы можете увидеть полную документацию и код https://github.com/tasmaniski/zf2-current-route< /а>

person tasmaniski    schedule 11.11.2015

Получить имя контроллера/действия в контроллере в среде Zend-3

private function getControllerActionName()
{
    $currentController = $this->getEvent()->getRouteMatch()->getParam('controller', 'index');
    $explode_controller = explode('\\', $currentController);
    $currentController = strtolower(array_pop($explode_controller));
    $currentController = str_replace('controller', '', $currentController);
    $currentAction = strtolower($this->getEvent()->getRouteMatch()->getParam('action', 'index'));
    return array(
            'controller' => $currentController,
            'action' => $currentAction,
        );
}

Меня устраивает. Надеюсь, это также поможет вам. Спасибо, что задали этот вопрос.

person Kamlesh    schedule 23.11.2019

person    schedule
comment
Я считаю, что вы можете изменить echoController() на __invoke() и изменить echo $controller; вернуть $контроллер - person Intellix; 25.10.2012
comment
Это решение даже лучше принятого (тоньше onBootstrap)! По логическим причинам я предлагаю поместить это в модуль Application вместо одного из ваших собственных модулей, поскольку вы можете вызывать $this->myviewalias() в любом представлении модуля. Как предложил Доминик, если вы используете __invoke() и возвращаете строку, вам не нужен ->echoController(), но если вы хотите использовать myviewalias для других целей, не используйте __invoke() и добавляйте дополнительные функции в помощник (например: другую функцию, которая возвращает действие ->getParam('action', 'index')). Надеюсь, поможет! - person Armfoot; 13.08.2013
comment
На самом деле принятый ответ редактирует функцию onBootstrap из Application\Module.php... Так что на самом деле это почти один и тот же ответ. Настоящая разница заключается в том, как каждый из них использует функции представления (с помощью __invoke() или независимых функций). - person Armfoot; 13.08.2013
comment
Если бы я сделал это сегодня, я бы зарегистрировал фабрику справки представления в методе Module::getViewHelperConfig() вместо того, чтобы настраивать ее в начальной загрузке. См. пример dstj ниже. Если помощнику нужно только эхо контроллера, метод __invoke() ведет к более тонким файлам представления. Если вы хотите, чтобы один и тот же помощник мог выводить другие вещи, такие как действие, то решение, приведенное выше, может быть предпочтительнее. - person Borje; 25.09.2013

person    schedule
comment
Не могли бы вы обернуть свой code-only-answer некоторыми комментариями? - person php-dev; 06.12.2016