Converting Zend config from ini to yaml. Non-obvious problems

I first knew about yaml from rails. And I really liked me. But unfortunatelly there wasn’t built in support of yaml in Zend Framework. However I started use yaml in my ZF apps. I added simple component that uses Symfony parser.


include_once 'SymfonyComponents/YAML/sfYaml.php';

 * Yaml decoder from Symfony
 * @author: radzserg
 * @date: 05.10.11
class App_Yaml

     * Load YAML
     * @static
     * @param $input file|yaml formatted text
     * @return array
    public static function load($input)
        $sfYaml = new sfYaml();
        return $sfYaml->load($input);

     * Dump array into YAML formatted text
     * @static
     * @param $array
     * @return string
    public static function dump($array)
        $sfYaml = new sfYaml();
        return $sfYaml->dump($array);


And finally in ZF 1.11.12 (I could mistaken here) Zend_Config_Writer_Yaml was added. So I’ve decided to convert application.ini to application.yml. Cause config in one of my project became bigger and bigger. I found ready solution in some blog and decided to use it.

$inputfile = APPLICATION_PATH . '/configs/application.ini';
$outputfile = APPLICATION_PATH. '/configs/application.yml';

$config = new Zend_Config_Ini($inputfile, null, array('allowModifications' => false, 'skipExtends'=> true));
$writer = new Zend_Config_Writer_Yaml();
$writer->write($outputfile, $config, true, true);
echo file_get_contents($outputfile);

Very simple and clear. I’ve scan received file. Looks good. All tests are passed. And I do the same on live server.

After few days we started getting errors about General error: 1205 Lock wait timeout exceeded; for some tables. I was checking mysql by SHOW PROCESSLIST and can’t find any blocking/competing query. I asked our admins to help but didn’t get any valuable info from them. The problem deal only with InnoDB tables, 90% of tables in our db are MyISAM. We were trying to check “show engine innodb status” but also found only not started transactions. Finally I tried to restart gearman workers (they are daemons and work for for a long time in Mysql) maybe this could help…
And I could execute the query. I tried to add force commit after every task execution. That helps. But the reason was still uncleared for me. Next day one of our customer couldn’t update some info. He did the query but nothing happened. I thought that admins could switch off AUTOCOMMIT for InnoDB in Mysql. Tried to do show variables like “%autocommit%”; from shell and got “ON”. Tried to do the same from php side and !!! got “OFF” how this could happen??? Everything worked ok untill this moment.

I looked once again into config and what did I find

resources.multidb.dbname.adapter = “pdo_mysql” = “localhost”
resources.multidb.dbname.username = “user”
resources.multidb.dbname.password = “pass”
resources.multidb.dbname.dbname = “dbname”
resources.multidb.dbname.driver_options.1002 = “SET NAMES utf8;”

was connverted to

      adapter: pdo_mysql
      host: localhost
      username: user
      password: pass
      dbname: dbname
        - SET NAMES utf8;

Look at SET NAMES utf8 and see that 1002 key is missing and now it’s equal to 0. And if you look into Zend_Db you’ll find
// PDO constant values discovered by this script result:

And finally the root of the problem Zend_Config_Writer_Yaml

     * Service function for encoding YAML
     * @param int $indent Current indent level
     * @param array $data Data to encode
     * @return string
    protected static function _encodeYaml($indent, $data)
        $result = "";
        $numeric = is_numeric(key($data));                // look here

        foreach($data as $key => $value) {
            if(is_array($value)) {
                $encoded = "\n".self::_encodeYaml($indent+1, $value);
            } else {
                $encoded = (string)$value."\n";
            $result .= str_repeat("  ", $indent).($numeric?"- ":"$key: ").$encoded;    // and look here
        return $result;

The most interesting that Symfony will convert it correct. Try to add $writer->setYamlEncoder(array(‘App_Yaml’, ‘dump’));

and it will work

Be careful when it deals with configs.

Leave a Reply

Your email address will not be published. Required fields are marked *