05/12/2010

PHP : dot2array, une couche d'abstraction pour utiliser facilement des tableaux à plusieurs dimensions.

Des fois on a du temps à tuer, du coup on entame un projet de programmation mais en avançant dedans on se retrouve à avoir besoin de code utilitaire réutilisable... et une fois que c'est fait on se dit qu'en fait c'est pratique et ça servirait bien à d'autres, donc que ce serait bien de le publier quelque part. Ici, je suis dans un train de retour de Strasbourg, et j'avais besoin d'un moyen simple et lisible de parcourir des tableaux multi-dimentionnels.

Sans plus attendre, voici le résultat de cette petite session improvisée, un exemple d'utilisation concrete de ces fonctions (en fait, leur raison d'être à la base) suit plus bas (et est disponible ici) :

<?php
// dot2array
// Abstraction layer allowing to get and set values from a multidimentional array
// by using a dot notation. Can be quite useful when working with configuration arrays.
// 2010, Jean-Karim Bockstael <jkb@jkbockstael.be>


// getValue : getter accessor
// Example : getValue($items, 'foo.bar.baz') = $items['foo']['bar']['baz']
function getValue($items, $itempath) {
    if (empty($items)) {
        throw new Exception("Could not get value: Empty items argument.");
    }
    if (empty($itempath)) {
        throw new Exception("Could not get value: Empty itempath argument.");
    }
    $names = explode('.',$itempath);
    $names = array_reverse($names);
    $item = &$items;
    while (count($names) > 0) {
        $name = array_pop($names);
        if (!isset($item[$name])) {
            throw new Exception("Could not get value: no value at this path.");
        }
        $item = &$item[$name];
    }
    return $item;
}

// setValue: setter accessor
// Example : setValue($items, 'foo.bar.baz', 42) => $items['foo']['bar']['baz'] = 42
function setValue(&$items, $itempath, $value) {
    if (empty($items)) {
        throw new Exception("Could not set value: Empty items argument.");
    }
    if (empty($itempath)) {
        throw new Exception("Could not set value: Empty itempath argument.");
    }
    if (empty($value)) {
        throw new Exception("Could not set value: Empty value argument.");
    }
    $names = explode('.',$itempath);
    $names = array_reverse($names);
    $item = &$items;
    while (count($names) > 0) {
        $name = array_pop($names);
        if (!isset($item[$name])) {
            $item[$name] = array();
        }
        $item = &$item[$name];
    }
    $item = $value;
}
?>

Les attentifs auront remarqué que le setter vérifie si un élement existe et le crée si besoin est. Maintenant, le pourquoi ! J'ai un fichier de configuration qui est de cette forme-là :

<?php
$configuration['database']['host'] = 'localhost';
$configuration['database']['name'] = 'DB-exemple';
$configuration['database']['user'] = 'user-exemple';
$configuration['database']['password'] = '5up3r53cr37';
$configuration['platform']['language'] = 'french';
$configuration['platform']['admin']['name'] = 'Jean-Karim Bockstael';
$configuration['platform']['admin']['email'] = 'jkb@jkbockstael.be';
// ...
?>

Doté de ceci, j'aimerais pouvoir faire quelque chose de ce goût-là :

<?php
// ...
$link = mysql_connect(getConfig('database.host'), getConfig('database.user'), getConfig('database.password'));
// ...
?>

En utilisant dot2array c'est possible, moyennant une fonction wrapper (allez, deux, c'est le même prix) :

<?php
require("dot2array.php");
require("configuration.php");

// Getter
function getConfig($itempath) {
    global $configuration;
    return getValue($configuration, $itempath);
}

// Setter
function setConfig($itempath, $value) {
    global $configuration;
    setValue($configuration, $itempath, $value);
}
?>

Elle n'est pas belle, la vie ? Allez hop, c'est cadeau (CC-BY, faut juste reconnaître que je suis un mec génial) donc profitez-en bien ;-) Téléchargement ici.


Tags:

cc-by | code (php) | dot2array


Pentes glissantes (17/03/2011)The Drums - The Drums (31/07/2010)