Перезапись конфигурационных файлов с помощью Zend_Config_Writer
Я уже давно начал использовать конфигурационные файлы и Zend_Config и писал про это, на мой взгляд это наиболее оптимальный способ хранить настройки. Понятный человеку формат - ini, позволяет не париться со скобками и запятыми при редактировании файла напрямую, в отличии от хранения конфигов в php формате т.е. массивах и уж тем более в таблице БД. Можно еще использовать XML,-формат но это уже непонятно зачем такая громоздкость. Вообщем все было здорово, но до какого-то момента не было готового компонента который позволял бы изменять конфигурации через веб интерфейс и нужно было писать разрабатывать решения. Потом он появился, об этом и пойдет речь, а именно о Zend_Config_Writer_Ini.
Использование Zend_Config_Writer_Ini.
Тут на самом деле все очень просто, если не вникать в подробности реализации абстрактного класса Zend_Config_Writer и адаптеров для него (Ini, Xml, Array). Вот код который позволяет это делать:
$config = new Zend_Config_Ini('/PATH/TO/config.ini', null, array("allowModifications" => true));
$config->site->name = '2Developers.Net';
$writer = new Zend_Config_Writer_Ini();
$writer->write('/PATH/TO/config.ini', $config);
Таким же образом, можно работать не только с ини-файлами, но и с эррэями и ИксЭмЭлем. Только тут несколько замечаний:
- само собой файл должен быть доступен для записи;
- опция allowModifications - должна быть передана при получении конфига, только тогда мы сможем изменять значения его свойств (как во второй строке).
Это то что касается записи конфигов и тут я ничего не придумал сам, а вот как это представить в web-интерфейсе... в админке например... у меня есть идея, правда недоработанная до-конца.
Отображение опций из конфигурационного файла для последующего редактирования.
Сначала попытаюсь объяснить, а потом выложу код.
Например может быть такая ситуация: в системе есть куча модулей и в дальнейшем будет еще больше, у них есть свои настройки в определенном ini-файле никто не знает что в них, но они хранятся в формате ini и их нужно вывести для возможности редактирования админом сайта.
Вот пример простого формата конфига:
[paginal]
title = "Постраничная навигация"
rows_per_page = "10"
[avatar_size]
title = "Аватары"
minwidth = "40"
maxwidth = "100"
minheight = "40"
maxheight = "100"
Опция title - "человеческое" название секции.
Можно написать такой экшн - он получает имя модуля и загружает его конфиги, потом передает ВИДу на вывод. Дальше получает новые значения от пользователя и сохраняет:
class Admin_SettingsController extends Zend_Controller_Action
{
public function moduleAction()
{
if (null === $module = $this->getRequest()->getParam('id')) {
// Если не передано имя модуля
throw new Zend_Controller_Action_Exception("Не передан параметр");
}
if (file_exists('/PATH/TO/modules/'.$module.'/config.ini')) {
// Если конфигурационный файл предусмотрен в модуле
$config = new Zend_Config_Ini('/PATH/TO/modules/'.$module, null, array("allowModifications" => true));
}
$this->view->assign("config", $config);
// Если пришли данные
if ($this->_request->isPost()) {
$params = $this->_request->getPost();
// Тут каждой опции присваивается новое значение, если оно было изменено
foreach ($params as $key => $val) {
foreach ($val as $k => $v) {
if ($config->$key->$k !== $v) {
$config->$key->$k = $v;
}
}
}
// Сохранение
$writer = new Zend_Config_Writer_Ini();
$writer->write('/PATH/TO/modules/'.$module.'/config.ini', $config);
$this->_redirect($this->view->url());
}
}
}
В скрипте вида следующее:
<?php if (sizeof($this->config) != 0) { ?>
<form action="<?php echo $this->url();?>" method="POST">
<?php foreach ($this->config as $key => $val): ?>
<fieldset>
<legend><?php echo $val->title; ?></legend>
<?php foreach ($val as $k => $v): ?>
<?php // все кроме title (название секции)
if ($k !== 'title') { ?>
<label for="<?php echo $k; ?>"><?php echo $k; ?></label>
<input type="text" name="<?php echo $key; ?>[<?php echo $k; ?>]" value="<?php echo $v; ?>" /><br />
<?php } ?>
<?php endforeach; ?>
</fieldset>
<?php endforeach; ?>
<input type="submit" value="Сохранить" />
</form>
<?php } else { ?>
<p><i>Модуль не содержит настроек</i></p>
<?php } ?>
Тут сложно понять, просто смотря, но стоит попробовать и все работает! А если это еще использовать с Zend_Form, то вообще будет отлично, например опции которые могут иметь только два значения true или false, можно было бы выводить как чекбоксы и т.д.
Только вот чего тут не хватает - нормальных названий опций, получается что напротив инпутов будут написаны такие вещи: "minwidth", "maxwidth" и т.д. но я так подозреваю, что это решаемо через Zend_Translate об этом я писал.