03. Zend_Config, файлы конфигурации, и содание помощников видов.
Настало время, пока не поздно, завести файл конфигурации для нашего приложения. Использовать будем конечно же Zend_Config, как написано в мануале - "это позволит нам получить преимущества простого объектно-ориентированного интерфейса", что же давайте проверим. Нам предоставляется возможность выбрать один из форматов конфигурационных данных и соответственно адаптер Zend_Config'а для работы с ним, пока это Zend_Config_Ini и Zend_Config_Xml.
Я остановился на ini-файле, для хранения конфигурационных данных. Могу это объяснить тем, что XML слишком громоздкий, во всяком случае для нашего приложения. Ini-файл же является "human readable", и парсится с помощью родной функции в php - parse_ini_file(), это занимает гораздо меньше времени. Конечно использование Zend_Config без адаптера тоже предусмотрено и работает еще быстрее, можно просто передавать php-файл конструктору класса Zend_Config, но в нашем примере мы пожертвуем 0.000001 секунды (образно) ради читабельности конфигов.
Основные настройки будем хранить в файле app/config.ini, остальные в каталоге app/configs/. Поехали:
app/config.ini
[view]
title_separator = " < "
[site]
name = "Демо сайт"
email = "support@2developers.net"
Добавим метод, выполняющий "загрузку" настроек в базовый контроллер (Divo_Controller), и свойство класса для их хранения.
Таким образом мы сможем получать данные из конфигурационного файла при каждом обращении к скрипту, в конструкторе базового контроллера, и иметь доступ к настройкам во всех дочерних контроллерах, через наследуемое свойство класса ($this->config). В результате добавления свойства, метода и его вызова в конструкторе, наш базовый контроллер примет вид:
lib/Divo/Controller.php
<?php
/** Базовый Класс между Zend_Controller_Action и нашими контроллерами действий.
Содержит базовые методы которые необходимо использовать в более чем одном контроллере */
require_once 'Zend/Controller/Action.php';
class Divo_Controller extends Zend_Controller_Action
{
/** @var object - Zend_Config */
protected $config;
public function init()
{
// первое, что сделаем - загрузим настройки
$this->config = $this->divoLoadConfig();
// Если каталог www расположен не в корне сервера (см. 11 строка www/index.php)
if (BASEURL !== "") {
$this->getRequest()->setBaseUrl(BASEURL.'/');
}
/** Настройки вида */
// Указываем где искать скрипты вида
$this->view->setScriptPath(APPPATH.'/views/');
// Берем из настроек разделитель для составных заголовков
$this->view->headTitle()->setSeparator($this->config->view->title_separator);
// Запустить layout
$this->_divoStartLayout();
$this->divoInit();
}
/** Используется вместо конструктора в дочерних контроллерах */
public function divoInit()
{ }
// Метод запускающий layout
private function _divoStartLayout()
{
require_once 'Zend/Layout.php';
// Полный список опций можно посмотреть в мануале
$options = array(
'contentKey' => 'content',
);
Zend_Layout::startMvc($options);
}
/** Загрузит конфиг. файл по умолчанию app/config.ini
* если $file не задано или равно config.ini
* в другом случае загрузит указанный файл из каталога app/config/
*
* Метод статический и может быть вызван как Divo_Controller::divoLoadConfig();
* @return object */
public static function divoLoadConfig($file = 'config.ini', $section = null)
{
if ($file != 'config.ini') $file = 'configs/'.$file;
require_once 'Zend/Config/Ini.php';
return new Zend_Config_Ini(
APPPATH.'/'.$file, // путь к файлу
$section, // секция ini-файла
array(
"allowModifications" => true // позволить изменять значения во время выполнения
)
);
}
}
Пример извлечения значения из объекта (строка 26).
Теперь в контроллерах можно обращаться к настройкам через свойство config, но в скриптах вида оно будет не доступно, это не удобно и поэтому следует написать хэлпер вида.
Создание помощников видов (View Helpers).
Сначала необходимо указать откуда их брать, для этого создадим каталог lib/Divo/Helper/View и добавим в конструктор базового контроллера следующие строки:
Divo_Controller::init()
// Путь к помощникам видов и префикс классов
$this->view->setHelperPath(LIBPATH.'/Divo/Helper/View', 'Divo_Helper_View');
Теперь сам хелпер. Помните что имя файла, имя класса без префикса (Divo_Helper_View) и название метода должны совпадать.
lib/Divo/Helper/View/Config.php
<?php
class Divo_Helper_View_Config {
public $config;
/** Извлекаем из реестра объект с настройками
(выполняется только при первом обращении к хелперу) */
public function __construct()
{
require_once 'Zend/Registry.php';
if (Zend_Registry::isRegistered('Zend_Config') === true) {
$this->config = Zend_Registry::get('Zend_Config');
}
}
// весь функционал помощника видов, заключен в одноименный метод
public function config()
{
return $this->config;
}
}
Как вы могли заметить, мы пытаемся получить объект из реестра, не положив его туда. Следующий код необходимо добавить в базовый контроллер ниже того места, где мы загружаем настройки:
lib/Divo/Controller.php
require_once 'Zend/Registry.php';
Zend_Registry::set('Zend_Config', $this->config);
Заключение
Теперь нам доступны настройки, в любом месте приложения, получить объект с конфигурационными данными можно следующими способами:
в контроллерах:
$this->config->example_option;
в скриптах вида, с помощью хелпера:
$this->config()->example_option;
везде:
1.
require_once 'Zend/Registry.php';
$this->config = Zend_Registry::get('Zend_Config');
2.
$this->config = Divo_Controller::divoLoadConfig();
Комментарии
Перестал выполнять примеры т.к. у меня не работает почему-то это в целом, но за отдельные темы как конфиги и хелпер для него респект, до этого асигнил конфиги в view где надо, а с хелпером удобнее получается
Я больше на это и расчитывал, но на всякий случай статьи связаны, вдруг кому так интереснее. Тем более в конце получится вполне работоспособное приложение, которые ты написал от начала до конца.
Неправильно это все выносить в контроллер. Почитайте http://devzone.zend.com/article/3372-Front-Controller-Plugins-in-Zend-Framework
Попробуйте прикрутить к своему примеру автоматический тест и сами в этом убедитесь.
Stepan Tanasiychuk, да знаю, руки не доходят переделать на версию с bootstrap'ом. Тут вот в каментах, тоже получил за это дело... Так что извините, исправлюсь... Но это все равно работает! ;) (понимаю, что в данном случае это не аргумент)
А чем этот вариант лучше передачи конфига в шаблоны?
clockworkbird, да в принципе наверно ничем не лучше - демонстрация Zend_Registry и создания Zend_View_Helper'ов, но и не хуже, мне так больше нравится, не нужно в каждом акшене передавать в шаблоны и соответственно париться - "передал не передал", не в каждом шаблоне конфиг может понадобиться.