Как сохранить пути application.ini с помощью Zend_Config_Writer_Ini
В настоящее время я работаю над системой сборки в Phing, которая берет шаблон проекта Zend Framework и настраивает его в соответствии с параметрами Phing. Одна проблема, с которой я столкнулся, - это использование Zend_Config_Writer_Ini.
Моя задача Phing берет предварительно заполненный файл из репозитория application.default.ini и модифицирует его с помощью Zend_Config_Ini для добавления параметров из файла сборки (подробности о БД и т. Д.). Затем он записывает его в application.ini, готовый для использования в проекте. Упрощенная версия кода связанной задачи выглядит примерно так:
$appConfig = new Zend_Config_Ini(
$appDefaultConfigPath,
null,
array(
'skipExtends' => true,
'allowModifications' => true
)
);
$appConfig->production->resources->db->params->host = $buildProperties->db->host;
$appConfig->production->resources->db->params->username = $buildProperties->db->username;
$appConfig->production->resources->db->params->password = $buildProperties->db->password;
$appConfig->production->resources->db->params->dbname = $buildProperties->db->dbname;
$writer = new Zend_Config_Writer_Ini();
$writer->setConfig($appConfig)
->setFilename($appConfigPath)
->write();
Это прекрасно работает, когда идут учетные данные базы данных, но когда дело доходит до предварительно заполненных путей, которые включают в себя определенные константы, что-то идет не так. Например:
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
будет выглядеть так:
bootstrap.path = "APPLICATION_PATH/Bootstrap.php"
Есть ли способ сохранить эти строки конфигурации при чтении / записи в разные INI-файлы, или я должен реструктурировать свой файл сборки, чтобы скопировать файл перед запуском задачи и изменить только те INI-строки, которые мне нужно изменить?
4 ответа
Когда вы загружаете существующий конфиг, все константы уже переведены, т.е. если вы посмотрите на объект с помощью print_r, вы больше не найдете свои константы. Следовательно, с писателем полный путь печатается вместо констант.
В вашем случае я предполагаю, что константы не существуют в вашей среде и поэтому печатаются как есть.
Обновление: чтобы быть более конкретным. Zend_Config_Ini::_parseIniFile()
использования parse_ini_file()
читать INI-файл, который загружает константы как реальные пути. Смотрите php.net doc Пример #2
В качестве альтернативы вы можете использовать фильтр Phing для замены токенов в шаблоне конфигурации.
Пример задачи:
<target name="setup-config" description="setup configuration">
<copy file="application/configs/application.ini.dist" tofile="application/configs/application.ini" overwrite="true">
<filterchain>
<replacetokens begintoken="##" endtoken="##">
<token key="DB_HOSTNAME" value="${db.host}"/>
<token key="DB_USERNAME" value="${db.user}"/>
<token key="DB_PASSWORD" value="${db.pass}"/>
<token key="DB_DATABASE" value="${db.name}"/>
</replacetokens>
</filterchain>
</copy>
</target>
Эта задача копирует application/configs/application.ini.dist
в application/configs/application.ini
и заменяет токены как ##DB_HOSTNAME##
со значением из свойства phing ${db.host}
Прямо из этого комментария php.net:
Константы в файлах ini не раскрываются, если они объединяются со строками, заключенными в одинарные кавычки, они должны быть в двойных кавычках только для расширения констант.
Пример:
define ('APP_PATH', '/ some / path');
mypath = APP_PATH '/ config' // Константа не будет расширена: [mypath] => APP_PATH '/ config'
mypath = APP_PATH "/ config" // Константа будет расширена: [mypath] => /some/path/config
Таким образом, вы можете переписать свои пути с одинарными кавычками... bootstrap.path = APPLICATION_PATH '/Bootstrap.php'
... а затем заменить все вхождения APPLICATION_PATH '*'
с двойными кавычками (простое регулярное выражение должно делать).
Я хотел удобство использования Zend_Config, сохраняя при этом возможность использовать константу APPLICATION_PATH, поэтому я в итоге исправил файл простым регулярным выражением после того, как Zend_Config_Writer сохранил файл.
$writer->write();
// Zend_Config_Writer messes up the settings that contain APPLICATION_PATH
$content = file_get_contents($filename);
file_put_contents($filename, preg_replace('/"APPLICATION_PATH(.*)/', 'APPLICATION_PATH "$1', $content));