Enum en php

j’ai fait il y a peu une formation java. Lorsque que l’on maitrise php5, je n’ai pas particulièrement été épaté par ce langage :-o

Mais une structure m’a tapé dans l’œil : les Enums et bien sur elle n’existe pas en php, mais on peut facilement trouver pas mal de propositions.

Sans rien de bien concluant après mes recherches j’ai décidé de me mettre au travail.

on débute par la fin voici une class « enum » oui/non :

class EnumOuiNon extends Enums {
    protected static $OUI = array('id'=>'ok', 'label'=>'c\'est bon',      'err'=>'is good');
    protected static $NON = array('id'=>'ko', 'label'=>'c\'est pas Bien', 'err'=>'is bad');
}

maintenant il faut l’utiliser :

echo EnumOuiNon::OUI();          
echo EnumOuiNon::OUI("id");      
echo EnumOuiNon::OUI("label");    
echo EnumOuiNon::OUI("en");
$es= EnumOuiNon::getItems();
foreach ($es as $e)    echo $e.' => '.EnumOuiNon::$e('label').' ';

A noter que c’est une classe statique (comme en java !) sinon c’était trop facile :)

Une petite aparté, une fois écrite, cette classe était en lecture-écriture ! ooops, c’est très bien ou très très mal ? Ne sachant pas y répondre, j’ai décidé par facilité qu’il sera possible de la bloquer en lecture uniquement; ma solution : un peu de réflexion :)

/**
 *@readonly
 */
class EnumDeux extends Enums {
    protected static ... ;
}

Ecrire EnumDeux::OUI(« label »,120) provoque une Exception
Enlevez le mot clé « readonly » et la il est possible de modifier cette valeur  EnumDeux::OUI(« label »,’nouvelle valeur’).

Enfin le code source de la classe Enums :

/**
 *@static
 *@author patrick chiffoleau
 */
class Enums   {
    final private function __construct(){    }

    private function parseDoc($classe){
        $ret=array();
        $reflection = new ReflectionClass($classe);
        $doc=$reflection->getDocComment();
        $nb = preg_match_all('/@\s*([a-z,A-Z]+)\s+/s',$doc,$matchs);
        if ($nb>0){
            foreach($matchs[1] as $k=>$v) $ret[strtolower($v)]=true;
        }
        return $ret;
    }

    public static function __callStatic($name,$args){
        $ret=null;
            $classe = get_called_class();
            if (!$args){ // lecture
                    $ret= $classe::${$name}['id'];
            }
            else {
                if (count($args)==1) // lecture
                        $ret=  $classe::${$name}[strtolower($args[0])];
                else {
                        // écriture
                        $docs=self::parseDoc($classe);
                        if (!key_exists('readonly',$docs)){
                            $classe::${$name}[$args[0]]=$args[1];
                            $ret=  $classe::${$name}[$args[0]];
                        }
                        else {
                            throw new Exception('Enums "<b>'.$classe.'</b>" est readonly (voir commentaires)');
                        }
                }  
            }
        return $ret;
    }

    public static function getItems(){
        $classe = get_called_class();
        $reflection = new ReflectionClass($classe);
        $Props = $reflection->getProperties(ReflectionProperty::IS_STATIC);
        unset($reflection);
        $ret=array();
        foreach ($Props as $p) $ret[]=$p->name;
        return $ret;
    }
    public static function getItem($name){
        $classe = get_called_class();
        return $classe::${$name};
    }
}

Voila, ce qui prend le plus de code c’est la fonctionnalité d’écriture.

Bon, je sais, ce n’ai pas exactement l’Enum de Java, mais la syntaxe est claire et l’utilisation simple, du vrai php quoi!

Share Button

Vous devriez aimer...