Как передать переменные в layout.phtml глобально в ZF2?

Я хочу передать ряд переменных в мой layout.phtml во всем приложении (глобально). И под этим я имею в виду, я не хочу использовать

$this->layout()->someVar = someValue;

в каждом действии, которое у меня есть, так как было бы много дополнительной работы и кода. Так есть ли способ сделать это только в одном месте? Или то, что я упомянул, это все, что я получил! Надеюсь нет:)

Может быть, с помощью сессий? - Реми Томас

Спасибо за решение. Пока что это то, что я использую. Для входа в систему пользовательской информации, настроек системы и макета, а также списка ACL. Но проблема в том, что мне нужно определить новый объект в layout.phtml, который я не считаю подходящим, не так ли? Я где-то читал, что любые данные, которые нам нужно использовать в моделях представления, должны передаваться ему с помощью действий контроллера. И особенно я не фанат срезания углов, поэтому, если есть чистый способ сделать это, я бы предпочел не делать это таким образом. И недавно мне нужно было получить количество непрочитанных сообщений для каждого пользователя и использовать его в layout.phtml. Так что, если я сделаю это в layout.phtml, это будет МНОГО PHP-скрипта внутри модели представления или макета.

Спасибо

6 ответов

Решение

Лучший и самый чистый способ - использовать ViewHelper, как предлагает Орочи. Вот несколько инструкций для создания собственного ViewHelper: http://framework.zend.com/manual/2.2/en/modules/zend.view.helpers.advanced-usage.html. Это не слишком сложно;)

Однако ваша проблема может быть решена и другим способом. Предположим, что переменные, которые вам нужны, содержат значения, предоставляемые сервисами, уже представленными в вашем приложении (а затем предоставленными ZF2 ServiceManager), вы можете добавить несколько строк в функцию "onBoostrap" внутри вашего Module.php (например, в модуле приложения).

Вот пример:

public function onBootstrap($e) {

    $serviceManager = $e->getApplication()->getServiceManager();
    $viewModel = $e->getApplication()->getMvcEvent()->getViewModel();

    $myService = $serviceManager->get('MyModule\Service\MyService');

    $viewModel->someVar = $myService->getSomeValue();

}

Таким образом, вы пишете назначение только в одном месте. Переменная затем доступна как обычно:

$this->layout()->someVar;

Это именно то, что вы хотите...

// Do this inside your Controller before you return your ViewModel
$this->layout()->setVariable('stack', 'overflow');

// Then inside your layout.phtml
echo $this->stack;

Нет помощников вида, нет менеджера событий, нет менеджера сервисов или других методов жонглирования. Почему люди в Stack иногда делают все так сложно?

В вашем Application/Module.php 1) Создайте событие Dispatch для Zend Framework следующим образом:

public function onBootstrap(MvcEvent $e)
{ 
    $eventManager        = $e->getApplication()->getEventManager();
    $eventManager->attach('dispatch', array($this, 'loadConfiguration' ));
}    
public function loadConfiguration(MvcEvent $e)
{           
      $controller = $e->getTarget();
      $controller->layout()->YOUR_VARIABLE_NAME = $YOUR_VALUE;
}

2) Теперь вы можете получить доступ к определенной вами переменной в вашем макете следующим образом: $this->YOUR_VARIABLE_NAME;

Создайте свой собственный ViewHelper для этого.

РЕДАКТИРОВАТЬ:

Вот как я это делаю: внутри папки src вашего модуля я создаю новую папку View, затем в этой папке View я создаю еще одну папку с именем Helper. В этой папке я создаю свои вспомогательные классы. Так, например, я создаю файл Navigation.php. В этом файле я создаю класс с именем Navigation, который выходит из AbstractHelper (используйте Zend\View\Helper\AbstractHelper). Затем я пишу код внутри публичной функции __invoke(), которая также возвращает некоторый результат. Вы также должны добавить свой вспомогательный класс view в 'view_helpers' внутри config/module.config.php модуля, что-то вроде этого:

'view_helpers' => array(
    'invokables' => array(
        'nav' => 'Application\View\Helper\Navigation',
    ),
),

Затем вы можете вызывать ваш 'nav' как метод в любом месте вашего представления или макета, например nav();?>

Вы можете передать глобальную переменную в ваш макет из Application/Module.php в ZendFramework 2, используя ModuleManager, как показано ниже:

В вашем приложении / Module.php

Шаг 1:

use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\Mvc\MvcEvent;

Шаг 2:

class Module implements AutoloaderProviderInterface, ConfigProviderInterface
{    
    public function onBootstrap(MvcEvent $e)
    { 
        $eventManager        = $e->getApplication()->getEventManager();
        $eventManager->attach('dispatch', array($this, 'loadConfiguration' ));
    }    
    public function loadConfiguration(MvcEvent $e)
    {           
          $controller = $e->getTarget();
          $controller->layout()->YOUR_VARIABLE_NAME = $YOUR_VALUE;
    }


  // Your remaining code here....

}

Шаг 3:

В вашем файле layout.phtml используйте вашу переменную как $this->YOUR_VARIABLE_NAME

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

Почему бы не использовать наследование для абстрагирования повторяемой конфигурации через базовый контроллер, который устанавливает переменные макета. Поскольку повторное использование является основной проблемой здесь, базового ООП должно быть достаточно. Зенд не должен делать все:).

Другие вопросы по тегам