Sébastien Caparros

Some developer's blog

Home (articles list)

Une classe String en PHP ?

Je souhaitais depuis quelque temps avoir en PHP une API plus propre pour gérer les chaînes de caractères. Difficile en effet de nier que l'API native - bien que très complète - est très mal foutue (je ne sais pas ce que je ferais sans la doc ...) et difficile à utiliser de manière optimale :

J'ai donc créé une classe intitulée NiceString (le mot clé "String" n'est pas réservé par le langage, mais ça ne me semble pas très prudent non plus de l'utiliser) que je partage sur GitHub.

On y retrouve les méthodes classiques de ce genre de classe, que je vous laisse découvrir (je me suis beaucoup inspiré de Java), mais je me suis surtout amusé avec les différentes méthodes et classes magiques de PHP. J'insiste sur le côté expérimental, je l'ai fait surtout pour le fun, c'est très probablement lent, et c'est horrible et élégant à la fois.

Interface ArrayAccess

Cette interface permet de surcharger les éléments de syntaxe des tableaux. En l'occurence,  ça permet d'utiliser isset et d'accéder à un caractère par son index : 

$truc = new NiceString("Bonjour");
isset($truc[1]) // ==> true
isset($truc[10]) // ==> false
echo $truc[1] // ==> "o"

Interface Iterator

Rien de très tordu ici, on peut simplement faire un foreach pour boucler sur chaque caractère de la chaîne.

Méthode __invoke

Cette méthode permet de gérer le cas dans lequel on essaye d'appeler l'objet comme une fonction. Je l'ai utilisé pour pouvoir récupérer une partie d'une chaîne de caractères :

$hw = new NiceString("Hello World!");
echo $hw(4, 8); // ==> "o Wo"

Méthode __get

Probablement celle avec laquelle je me suis le plus amusé. On ne peut pas surcharger l'opérateur de concaténation en PHP (caractère "."). Mais j'ai trouvé un moyen détourné de concaténer en utilisant l'opérateur de pointage ("->").

Avant de vous montrer le résultat, je vais rappeler quelques points importants et méconnus du langage : 

$a = "Hello World!";
$b = "a";
$c = "b";
$d = "c";

echo $$$$d; // ==> "Hello World!"

J'ai donc utilisé la méthode __get pour retourner un autre objet NiceString, ce qui permet d'enchaîner avec des choses comme ça : 

$people = "World";
const MY_NAME = 'FooBar';
$age = 42;

$hello = new NiceString("Hello ");

echo $hello->$people->{", my name is "}->{MY_NAME}->{" and I'm "}->$age->{" years old.\n"};

(ce code affichera "Hello World, my name is FooBar and I'm 42 years old.")

OK, c'est horrible d'un point de vue sémantique et syntaxique, mais avouez que c'est astucieux :P ?

 

Je partage tout ça sous licence MIT, mais c'est très expérimental, utilisez le à vos risques et périls !