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 include_once('/path/to/sf1.1/lib/yaml/sfYaml.class.php'); // Load the YAML file $array = sfYaml::load('test.yml'); // Check what we have got print_r($array);
Well, that is all we need to test parsing and creating YAML files! Let's create a test.yml
file:
root: level1: sublevel11: value11 sublevel12: value12 level2: 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:
Array
(
[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:
root:
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:
root:
level1:
sublevel11: value11
sublevel12: value12
level2:
sublevel21: value21
sublevel22: value22
level3:
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:
propel:
prd_alert:
_attributes:
idMethod: native
id:
type: INTEGER
required: true
autoIncrement: true
primaryKey: true
dummy:
type: INTEGER
begin_at:
type: TIMESTAMP
Now enjoy the output using the new library:
propel:
_attributes:
package: lib.model
admin:
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 :)