En este tutorial vamos a aprender un poco sobre qué es y como escribir un YAML o YML básico para crear archivos o clases de configuración para nuestros proyectos en PHP...

¿Qué es YAML?



YAML es un lenguaje de marcado "ligero" que permite especificar estructuras (tales como arrays) con menos caracteres que XML, de forma sencilla.

YAML es usado en frameworks de PHP tales como Symfony dada su facilidad de uso y lo amigable que puede resultar su edición y lectura para los seres humanos.

Ejemplo explicado de un YAML



Para comenzar vamos a dar un ejemplo de código YAML:

Código :

default language: es
other languages: [en, it]

default controller:
  web: home
  admin: login

controller alias:
  es:
    acerca: about
    contacto: contact
    busqueda: search



Como pueden notar el código YAML es sumamente sencillo...

Vamos a desglosarlo:

Código :

default language: es


Significa, como es de suponer, la asignación del valor 'es' a la "variable" 'default language'.

En el caso de:

Código :

other languages: [en, it]


Estaríamos definiendo una "variable" llamada 'other languages' que contendría un "array" con los valores "en" y "it"

También podemos anidar las definiciones o crear "arrays asociativos", como hago aquí:

Código :

default controller:
  web: home
  admin: login


En este caso "default controller" guardaría los indices "web" y "admin" con los valores "home" y "login" respectivamente...

Un par de cosas importantes:


  1. Para indexar debemos usar espacios
  2. Como se fijan podemos usar espacios y escribir sin comillas, a menos que usemos caracteres reservados que en YAML se definen como "indicator characters"


¿Cómo leer YAML en PHP?



Ahora, he nombrado "variables" y "arrays" entre comillas porque para PHP leer nuestro código YAML no sería muy diferente a leer texto plano, necesitamos una clase que nos convierta dicho YAML en código PHP para poder usarlo en nuestra aplicación. Para ello usaremos spyc.

spyc es una clase escrita en PHP que nos permite leer un YAML y convertirlo en un array de PHP o viceversa...

Para usar spyc debemos descargar la biblioteca y descomprirmla.

Ahora supongamos que tenemos guardado el YAML en /config/Test.yaml para leerla incluímos la biblioteca spyc y luego usamos la siguiente función:

Código PHP :

require_once('spyc/spyc.php');
$data = Spyc::YAMLLoad('/config/Test.yaml');


ahora si hacemos un print_r de $data obtendremos lo siguiente:

print_r escribió:


Array
(
[default language] => es
[other languages] => Array
(
[0] => en
[1] => it
)

[default controller] => Array
(
[web] => home
[admin] => login
)

[controller alias] => Array
(
[es] => Array
(
[acerca] => about
[contacto] => contact
[busqueda] => search
)

)

)


Con esto ya podríamos obtener y usar los valores de nuestro YAML, pero me parece que sería algo pesado tener que leer los YAML y convertirlos a PHP una y otra vez...

Por ello vamos a:

Convertir nuestro YAML en un archivo temporal de PHP



...Que usaremos como archivo temporal para leer los valores cuando haga falta...

Para ello concatenaremos algo de código php, usando la función de PHP var_export para convertir nuestro array en una cadena de código PHP que podamos guardar en un archivo, de esta forma:

Código PHP :

   $phpCode = '$data = ' . var_export($data, TRUE); . ';'
   echo $phpCode;


Con esto sólo nos faltaría guardar el código en un archivo en vez de imprimirlo. Primero, vamos a crear una carpeta llamada "tmp" (asignamos permisos 777 si estamos en sistemas *NIX) y luego usaremos file_put_contents dentro del código PHP, así:

Código PHP :

<?php

   require_once('spyc.php');
   $data = Spyc::YAMLLoad('config/Test.yaml');
   
   $phpCode = '$data = ' .var_export($data, TRUE). ';';
   
   file_put_contents('tmp/Test.php', "<?php\n\n" . $phpCode . "\n\n?>");

?>


Si todo va bien, nuestro código habrá creado el archivo Test.php en la carpeta tmp/ que contendrá algo como lo siguiente:

Código PHP :

<?php

$data = array (
  'default language' => 'es',
  'other languages' => 
  array (
    0 => 'en',
    1 => 'it',
  )..............................................................


De esta forma, si existe el archivo PHP temporal, podríamos leerlo en vez de leer el YAML, pero, ¿Qué pasaría si modificamos nuestro YAML? Lo ideal sería borrar el php temporal y volver a compilarlo, para ello usaremos la siguiente función:

Código PHP :

   function isCompiled($originalFile, $compiledFile)
   {
      if (file_exists($compiledFile))
      {
         //TODO: colocarle el compile check...
         
         if (filemtime($originalFile) < filemtime($compiledFile))
         {
            return TRUE;
         }
      }
      
      return FALSE;
   }


Esta función acepta 2 direcciones de archivos como parámetros, el archivo original que debe existir y el compilado; entonces verifica que el compilado exista y la fecha de modificación de éste sea mayor a la fecha de modificación del archivo original, si es así, quiere decir que el archivo original no ha sufrido cambios y podemos leer el archivo compilado con confianza =)

Entonces el código final nos quedaría:

Código PHP :

<?php

   function isCompiled($originalFile, $compiledFile)
   {
      if (file_exists($compiledFile))
      {
         //TODO: colocarle el compile check...
         
         if (filemtime($originalFile) < filemtime($compiledFile))
         {
            return TRUE;
         }
      }
      
      return FALSE;
   }
   
   $originalFile = 'config/Test.yaml';
   $compiledFile = 'tmp/Test.php';

   if(!isCompiled($originalFile, $compiledFile))
   {
      require_once('spyc.php');
      $data = Spyc::YAMLLoad($originalFile);
      
      $phpCode = '$data = ' .var_export($data, TRUE). ';';
      file_put_contents($compiledFile, "<?php\n\n" . $phpCode . "\n\n?>");
   }
   else
   {
      require($compiledFile);
   }
   
   echo "<pre>";
   echo var_dump($data);
   echo "</pre>";

?>


Por supuesto que para darle un uso más práctico a nuestro ejemplo, podríamos definirlo enmarcarlo en una clase o en una función, haciendo que 'Test.yaml' sea $nombreArchivo . 'yaml'... También el código temporal que se genera podría ser no una variable con un array, sino una clase... Pero vamos a dejarlo por ahora hasta aquí que se está haciendo muy largo esto ;)

Si quieren saber más sobre la documentación de YAML pueden verla aquí, también si quieren una alternativa a spyc para trabajar con YAML tienen la clase que usa symfony

Espero que les haya gustado el YAML y este tutorial ^_^.