开发者

How to preserve application.ini paths using Zend_Config_Writer_Ini

I'm currently working on a build system in Phing that takes a Zend Framework project template and configures it according to Phing parameters. One problem that I've come across is when using Zend_Config_Writer_Ini.

My Phing task takes a pre-pop开发者_运维知识库ulated file from the repo called application.default.ini and modifies this using Zend_Config_Ini to add parameters from the build file (db details, etc). It then writes it to application.ini ready for the project to use. A simplified version of the related task code looks something like this:

$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();

This works fine as far as the database credentials go but when it comes to pre-populated paths that include defined constants something goes wrong. For example:

bootstrap.path = APPLICATION_PATH "/Bootstrap.php"

becomes:

bootstrap.path = "APPLICATION_PATH/Bootstrap.php"

Is there any way to preserve these config lines when reading/writing to different ini files or should I restructure my build file to copy the file before running the task and only modify the ini lines that I need to change?


When you load the existing config all constants are already translated, i.e. if you look at the object with print_r you won't find your constants anymore. Hence, with the writer the full path is printed instead of the constants.

In your case I guess that the constants don't exist in your environment and therefore are printed as is.

Update: To be more specific. Zend_Config_Ini::_parseIniFile() uses parse_ini_file() to read the ini file which loads the constants as real paths. See php.net doc Example #2


Straight from this php.net comment:

Constants in ini files are not expanded if they are concatenated with strings quoted with single quotes, they must be in double quotes only to make constants expanded.

Example:

define ('APP_PATH', '/some/path');

mypath = APP_PATH '/config' // Constant won't be expanded: [mypath] => APP_PATH '/config'

mypath = APP_PATH "/config" // Constant will be expanded: [mypath] => /some/path/config

So you could rewrite your pathes with single quotes ... bootstrap.path = APPLICATION_PATH '/Bootstrap.php'

... and later replace all occurrences of APPLICATION_PATH '*' with double quotes (a simple Regex should do).


As an alternative you could use Phing's Filter to replace tokens in your configuration template.

A example task:

<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>

This task copies application/configs/application.ini.dist to application/configs/application.ini and replaces tokens like ##DB_HOSTNAME## with the value from the phing property ${db.host}


I wanted the convenience of using Zend_Config while preserving the ability to use the APPLICATION_PATH constant so I ended up fixing the file with a simple regex after Zend_Config_Writer saves the file.

$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));
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜