Manuel de référence → Hoa_Configuration

Chapitre 7. Hoa_Configuration

Toutes les applications sont basées sur des fichiers de configuration. Ces fichiers permettent de modifier la façon dont l'application va se comporter et sont donc nécessaires si on veut une application orientée utilisateur.

Les fichiers de configuration sont souvent écrits dans les formats XML, INI, PHP ou encore YAML. Hoa propose de lire ces fichiers, et de les consulter de façon simple et rapide.

Sortie standard des configurations

Pour une utilisation plus souple et plus facile des fichiers de configuration, Hoa a adopté une sortie standard quelque soit le type de fichier de configuration. C'est à dire que si on utilise un fichier XML, YAML, PHP ou INI, la façon d'exploiter les données du fichier seront identiques.

Préparer la lecture

Pour faciliter l'utilisation du paquetage Hoa_Configuration, on ne se base pas sur une fabrique, mais sur les règles de nommages.

Ainsi, tous les paquetages commencent par : Hoa_Configuration_ et sont suivis du format que l'on souhaite utiliser. Si on veut utiliser le format INI, alors on demandera l'instance du paquetage : Hoa_Configuration_Ini, et ainsi de suite pour les autres formats. On aura quelque chose de semblable à :

<?php
 
set_include_path( ... );
require_once 'Framework.php';
import('Configuration.Ini');
 
/**
 * On demande l'instance de la
 * configuration des fichiers INI.
 */
$config = new Hoa_Configuration_Ini( ... );

Chaque objet de configuration par type de fichier a un constructeur différent. Cela se conçoit facilement, car chaque type de fichier n'a pas les mêmes besoins d'analyse ; un tableau se lit de façon naturelle, alors qu'un fichier INI a besoin de paramètres de lecture.

Sortie en objet Hoa_StdClass

Il y a deux façons d'exploiter les données de configurations. La première, et celle par défaut, est la sortie en objet Hoa_StdClass. Cet objet offre des possibilités qui ne sont pas forcément évoquées ou détaillées dans ce chapitre, on conseille alors de lire le Chapitre 25, Hoa_StdClass.

Accès aux variables

L'objet Hoa_StdClass se comporte comme l'objet StdClass de PHP en offrant des possibilités supplémentaires. Tout d'abord, on va regarder comment on accède aux données :

/**
 * Soit la structure suivante :
 */
(
    'a' => 'AaA',
    'b' => 'bBb',
    'c' => (
        'x' => 'XxX',
        'y' => 'yYy',
        'z' => 'Zzz'
    )
);
 
/**
 * Alors on atteint les données de
 * cette façon :
 */
echo $structure->c->y;

Cela nécessite, dans le cas de la sortie Hoa_StdClass, que toutes les « clés » respectent le motif des variables de PHP, à savoir :

[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

Si ce n'est pas le cas, une exception Hoa_StdClass_Exception sera levée.

La racine des configurations s'obtient en appelant la méthode get de l'objet Hoa_Configuration.

Parcourir les configurations

L'objet Hoa_StdClass implémente l'interface Iterator ce qui nous permet de placer les configurations dans des boucles afin de le parcourir :

$config = new Hoa_Configuration_xxx( ... );
 
/**
 * On parcourt tout le sous-niveau c.
 */
foreach($config->c as $key => $value)
    echo $key . ' : ' . $value . "\n";

Les configurations peuvent être sous forme d'arbre, donc lors d'un parcours, la valeur peut être un nouvel arbre. Pour savoir si c'est le cas, Hoa_Configuration propose la méthode isRecursive qui retourne true s'il y a un sous-arbre, un sous-niveau, false sinon.

Afficher les configurations

Pour se représenter plus facilement l'arbre des configurations sous forme d'objet, on peut l'afficher directement. Le résultat ressemblant sensiblement à la sortie de print_r :

echo $config;
 
/**
 * Affichera :
 *
 * Hoa_StdClass (
 *     [a] => AaA
 *     [b] => bBb
 *     [c] => Hoa_StdClass (
 *         [x] => XxX
 *         [y] => yYy
 *         [z] => Zzz
 *     )
 * )
 */

Transformer l'objet en tableau

Il peut arriver que l'on veuille transformer notre sortie objet en tableau. Pour ça, l'objet Hoa_StdClass propose la méthode toArray. Il faut appliquer cette méthode sur un nœud ou à la racine des configurations :

/**
 * On transforme nos configurations sous forme d'objet
 * vers un tableau.
 */
print_r($config->get()->toArray());
print_r($config->c->toArray());

Sortie en tableau

Par défaut, la sortie est sous forme d'objet Hoa_StdClass, mais on a la possibilité de désactiver cette conversion à l'aide du dernier paramètre de chaque constructeur : CONVERT_TO_OBJECT pour activer la conversion, CONVERT_TO_ARRAY sinon. Ces constantes sont disponibles sur la classe Hoa_Configuration.

Manipulation des données

L'accès aux variables, le parcours des configurations, ou l'affichage se fait de façon naturelle, à l'aide des fonctions PHP, à savoir :

/**
 * On désactive la conversion en objet.
 */
$config = new Hoa_Configuration_xxx( ... , ... , Hoa_Configuration::CONVERT_TO_ARRAY);
 
/**
 * On accède aux données.
 */
echo $config['c']['y'] . "\n";
 
/**
 * On parcours les configurations.
 */
foreach($config['c'] as $key => $value)
    echo $key . ' : ' . $value . "\n";
 
/**
 * On affiche les configurations.
 */
print_r($config['c']);

Pour atteindre la racine des configurations, on appelle également la méthode get.

Pour savoir s'il y a un sous-niveau, on utilise également la méthode isRecursive.

La méthode get

Si on veut atteindre le niveau 0 (la racine) des configurations, on doit appeller la méthode get sur notre objet de configuration.

À partir d'un tableau

On a vu que les configurations peuvent être stockées sous différentes formes. Une des formes les plus simples est un tableau déclaré en PHP.

On procéderait de la façon suivante :

<?php
 
set_include_path( ... );
require_once 'Framework.php';
 
import('Configuration.Array');
 
$array = array(
    'a' => 'AaA',
    'b' => 'bBb',
    'c' => array(
        'x' => 'XxX',
        'y' => 'yYy',
        'z' => 'Zzz'
    )
);
 
$config = new Hoa_Configuration_Array($array);
 
echo 'En mode : ' . $config->c->z;
 
/**
 * Affichera :
 *     En mode : Zzz
 */

Il est préférable pour de moyennes ou grosses applications d'écrire les configurations dans un fichier à part. On appelle Config.php ce fichier, et il sera de la forme suivante :

<?php
 
return array(
    'a' => 'AaA',
    'b' => 'bBb',
    'c' => array(
        'x' => 'XxX',
        'y' => 'yYy',
        'z' => 'Zzz'
    )
);

Alors on aura simplement à faire :

$config = new Hoa_Configuration_Array(require 'Config.php');

Ce qui reviendra au même. L'exploitation des données restera la même que précédemment.

Si on veut préférer une sortie sous forme d'un tableau plutôt que de l'objet Hoa_StdClass, il suffit de passer un second paramètre : un booléen à faux :

$config = new Hoa_Configuration_Array(
              require 'Config.php',
              Hoa_Configuration::CONVERT_TO_ARRAY
          );
 
echo 'En mode : ' . $config['c']['z'];

À partir d'un fichier INI

Exploitation des données

On peut également exploiter les configurations stockées dans un fichier INI. Pour cela, on procédera de la façon suivante :

<?php
 
set_include_path( ... );
require_once 'Framework.php';
 
import('Configuration.Ini');
 
$config = new Hoa_Configuration_Ini('Config.ini');

Si on veut reprendre les exemples précédents, alors le fichier Config.ini ressemblera à ceci :

a   = AaA
b   = bBb
c.x = XxX
c.y = yYy
c.z = Zzz

Accéder à une catégorie

Les fichiers INI peuvent être construits en catégories, i.e. partagées en plusieurs parties :

[db]
host               = localhost
user               = root
pwd                = 
dbname             = base
 
[lang]
locale.timezone    = Europe/Paris
locale.region      = Franche-Comté
locale.departement = Doubs
encoding           = utf-8

Pour simplifier les traitements, on peut manipuler seulement une seule catégorie. Pour cela, on passe le nom de la catégorie en second paramètre du constructeur de Hoa_Configuration_Ini :

$config = new Hoa_Configuration_Ini('Config.ini', 'db');
 
/**
 * On ne parcourt que les configurations
 * de la base de données.
 */
foreach($config->get() as $key => $value)
    echo $key . ' ' . $value . "\n";

Et enfin, le troisième paramètre sert à désactiver la sortie sous forme de l'objet Hoa_StdClass pour activer la sortie sous forme d'un tableau :

$config = new Hoa_Configuration_Ini('Config.ini',
                                    'db',
                                    Hoa_Configuration::CONVERT_TO_ARRAY);
 
foreach($config->get() as $key => $value)
    echo $key . ' ' . $value . "\n";

Échapper les points

On remarque que le point (.) est le séparateur de niveau dans les fichiers INI. Il est possible de les échapper avec Hoa, en les précédent d'un anti-slash (\) :

on.echappe\.un.point = hopla

Attention, si le fichier est converti en Hoa_StdClass le point sera transformé en trait de soulignement (underscore, _). À manipuler avec précaution donc.

À partir d'un fichier XML

XML est un langage de sérialisation plutôt pratique car très répandu. En général, les autres langages le comprennent assez bien, et il a l'avantage de se présenter directement comme un arbre.

Exploitation des données

L'analyse des fichiers XML se fait à l'aide du paquetage Hoa_Xml (voir le Chapitre 31, Hoa_Xml). Le constructeur de Hoa_Configuration_Xml prend donc en premier paramètre le fichier qui contient les configurations, puis l'encodage du fichier, et pour finir l'activation de la conversion vers une sortie objet :

import('Configuration.Xml');
 
$config = new Hoa_Configuration_Xml('Config.xml');

On aurait un fichier qui ressemblerait à (avec une en-tête qui précise la version et l'encodage) :

<configuration>
  <db>
    <host>localhost</host>
    <user>root</user>
    <pwd></pwd>
    <dbname>base</dbname>
  </db>
  <lang>
    <locale>
      <timezone>Europe/Paris</timezone>
      <region>Franche-Comté</region>
      <departement>Doubs</departement>
    </locale>
    <encoding>utf-8</encoding>
  </lang>
</configuration>

Et on accéderait aux données de cette façon :

echo $config->lang->locale->region . "\n";
 
/**
 * Affichera :
 *     Franche-Comté
 */

Le problème avec les nombres

Dans XML, il peut arriver que l'on ait plein de fois la même balise à un même niveau, c'est ce qu'on appelle le multi-balisage[8]. Dans ce cas, on a une liste ordonnée des balises (on conseille vraiment d'aller voir le chapitre concerné). Dans le cas d'une sortie Hoa_StdClass, les variables ne peuvent pas être entières[9]. La solution qui a été retenue est de préfixer les entiers par un trait de soulignement (underscore, _), si on a demandé cette sortie. Pour un tableau rien ne change.

On pourrait alors avoir :

<configuration>
  <test>
    <bidule>machin</bidule>
  </test>
  <test>
    <truc>hopla</truc>
  </test>
</configuration>

On y accéderait de cette façon :

echo $config->test->_0->bidule;
 
/**
 * Affichera :
 *     machin
 */

On rappelle que ce problème n'a pas lieu avec une sortie en tableau.

À partir d'un fichier YAML

YAML est un langage de sérialisation très pratique car orienté humain. C'est un langage suffisament puissant pour nous servir de fichier de configuration. On trouvera plus d'informations sur le langage en lisant sa spécification : Specification of YAML Ain't Markup Language (YAML) Version 1.1.

Exploitation des données

Hoa_Configuration_Yaml analyse les fichiers à l'aide du paquetage Hoa_Yaml (voir le Chapitre 33, Hoa_Yaml), on retrouve donc les mêmes options que le constructeur pour le constructeur de Hoa_Configuration_Yaml (avec, en plus, la possibilité de ne pas convertir les configurations en objet Hoa_StdClass).

On aura quelque chose de semblable à ça :

import('Configuration.Yaml');
 
$config = new Hoa_Configuration_Yaml('Config.yml');

On aurait un fichier de configuration qui serait susceptible de ressembler à ceci :

host: localhost
user: root
pwd:
dbname: base

On accéderait aux données de cette façon (comme déjà vu précédemment) :

echo $config->host . "\n";

Accéder à un document

Un document YAML peut contenir plusieurs sous-documents, comme si le fichier en contenait plusieurs autres. Ces documents sont numérotés de 0 à n, et on y accède en passant un entier en second paramètre du constructeur. Par défaut, on sélectionne le premier document (donc d'index 0).

On aurait alors :

$config = new Hoa_Configuration_Yaml('Config.ini', 2);

On rappelle que les documents sont séparés par trois traits d'union (---) :

# Premier document (index 0).
---
host: localhost
user: root
pwd: 
dbname: base
 
# Second document (index 1).
---
etc: bla bla bla

Et enfin, le dernier paramètre spécifie si on veut que les configurations soient converties en objet Hoa_StdClass ou pas. Pour avoir un tableau en sortie, on aura :

$config = new Hoa_Configuration_Yaml('Config.yml',
                                     0,
                                     Hoa_Configuration::CONVERT_TO_ARRAY);

Le problème avec les nombres

Dans YAML, on travaille beaucoup avec des listes ordonnées. Le problème, si on a choisi une sortie Hoa_StdClass, est que les nombres ne peuvent pas constituer une variable[10]. La solution qui a été trouvée est que tous les nombres sont préfixés d'un trait de soulignement (underscore, _) si on a demandé cette sortie. Pour un tableau, rien ne change.

On pourrait alors avoir :

bob:
  - bill: le chien
  - billy: le crabe

On y accéderait de cette façon :

echo $config->bob->_1->billy;
 
/**
 * Affichera :
 *     le crabe
 */

On rappelle que ce problème n'a pas lieu avec une sortie en tableau.


[8] Dans le vocabulaire du paquetage Hoa_Xml du moins.

[9] Excepté si elles sont dynamiques, mais ce n'est pas le cas ici.

[10] Excepté si elle est dynamique, mais ce n'est pas le cas ici.