Как сохранить пути 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));
Другие вопросы по тегам