YAML in symfony 1.1

Here is a short tutorial about my discovery of the new YAML parsing library that comes with symfony 1.1. As you may know, YAML files are a place symfony developpers spend time writing configuration, it is very important they have a good tool to manipulate data and debug files. Giving trainings on symfony 1.0 is a part of my job and when I see people starting the configuration files, I can notice the YAML system in the first version of symfony has two major problems:

  • The error messages do not help developers finding their mistakes in a YAML file.

  • Converting PHP data into a YAML structure can produce messy outputs.

Lets play with YAML!

The first good new is you do not have to use symfony to take advantage of this new library. As I needed it for a non symfony project (that's sad, I know), the only thing I had to do was to include the sfYaml.class.php file in my script.

// Include the symfony YAML library
// Load the YAML file
$array = sfYaml::load('test.yml');
// Check what we have got

Well, that is all we need to test parsing and creating YAML files! Let's create a test.yml file:

    sublevel11: value11
    sublevel12: value12
     sublevel21: value21
    sublevel22: value22

Error messages

Some of you acquainted with YAML syntax might have noticed the indentation error I have on the sublevel21 line. Let's run our test.php file. It will explode on the screen showing the following error:

Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Unable to parse file "test.yml": Indentation problem at line 6 ( sublevel22: value22)' in /path/to/sf1.1/lib/yaml/sfYaml.class.php:70
Stack trace:
#0 /var/www/sites/test/-(7): sfYaml::load('test.yml')
#1 {main}
thrown in /path/to/sf1.1/lib/yaml/sfYaml.class.php on line 70'

Most of us have a difficult time when beginning with YAML because of its uncompromising syntax. The library used in symfony 1.0 was of course working well but it has crypting error messages that let you spend hours looking for the tab character lost alone at the end of your file. You can see here the message is clear: Indentation problem at line 6. In case of the presence of tabs in our file, we would have Unable to parse file "test.yml": A YAML file cannot contain tabs as indentation line .... The second good thing is this error is propagated with an exception so it is catchable.

With such information, we can fix our mistake quickly. The php script then obediently outputs the following:

    [root] => Array
            [level1] => Array
                    [sublevel11] => value11
                    [sublevel12] => value12

            [level2] => Array
                    [sublevel21] => value21
                    [sublevel22] => value22



That was as easy as that.

Dumping YAML

Let's now try to modify the array and generate the according YAML structure:

// Add an extra level to our array
$array['root']['level3'] = array('sublevel31' => 'value31', 'sublevel32' => 'value32');
// print the YAML out on the screen
echo sfYaml::dump($array);

This will produce the following output:

  level1: { sublevel11: value11, sublevel12: value12 }
  level2: { sublevel21: value21, sublevel22: value22 }
  level3: { sublevel31: value31, sublevel32: value32 }

This isn't really what we expected. Well, in fact, sfYaml::dump() can take an extra inline argument. When the inline depth is reached, the rest of the structure is dumped as YAML associative array. We just have to specify an inline level of 3:

echo sfYaml::dump($array, 3);

This will give us:

    sublevel11: value11
    sublevel12: value12
    sublevel21: value21
    sublevel22: value22
    sublevel31: value31
    sublevel32: value32

This is particularly convenient when dumping YAML schema from a database with propel:build-schema. With symfony 1.0 we were used to obtain something dirty like:

      idMethod: native
      type: INTEGER
      required: true
      autoIncrement: true
      primaryKey: true
      type: INTEGER
      type: TIMESTAMP

Now enjoy the output using the new library:

    package: lib.model
    id: { type: INTEGER, required: true, primaryKey: true }
    login: { type: VARCHAR, size: '255', required: true }
    created_at: { type: TIMESTAMP }
    _indexes: { admin_login_idx: [login] }

You can use the sfYaml library with your non symfony applications exactly the way we did here. This tool is also bundled with symfony 1.1 so you can use it directly out of the box in your actions or your tasks.

I have been using symfony 1.0 and I had great pleasure discovering it and working with it. Now, I am using symfony 1.1 and discovering features like this one, I found the same pleasure again.


New error messages are great. They will help lot of debugging.
Nice! I'm a big fan of yaml ... and symfony of course!
Those were the only 2 issues I ever had with yaml. It's so cool how you sf guys keep solving all the right problems. YAY :)

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.