Standard PHP Library de PHP5 : Présentation et exemples.
Si vous êtes un développeur PHP, que vous aimiez les arrays, l’orienté objet et les design patterns, cet article est pour vous. Lors d’une discussion dernièrement avec un ami, il a attiré mon attention que plusieurs développeurs qui ne connaissent pas forcement ce que rajoute cette version par rapport à la version 4.
J’ai décidé alors de couvrir un ajout essentiel de PHP5 : La librairie SPL, acronyme de Standard PHP Library, qui tend a résoudre des défis de programmation communes en offrant une serie de classes, interfaces et fonctions.
La librairie est disponible depuis la version 5.0, et pour encore souligner l’importance de SPL : depuis la version 5.3, il est impossible de la désactiver de la source.
SPL est développée par Marcus Boerger, un développeur du core de PHP et un contributeur a plusieurs extensions comme APC, Xdebug, PDO ainsi que des composants PEAR.
Sommaire
Les interfaces diverses
ArrayObject
L’interface la plus courante dans cette rubrique est ArrayObject. Avec ArrayObject, On peut traiter un object comme un tableau. On peut alors itérer sur les éléments de l’objet, par exemple :
$myArray = array ( 'time' =>'Derick Rethans',
'test' => 'Sebastian Bergmann',
'iterate' => 'Marcus Börger',
);
$obj = new ArrayObject($myArray);
print_r($obj);
$obj->uasort(function ($a, $b) {
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
});
print_r($obj);
ce qui affiche
ArrayObject Object
(
[storage:ArrayObject:private] => Array
(
[time] => Derick Rethans
[test] => Sebastian Bergmann
[iterate] => Marcus Börger
)
)
ArrayObject Object
(
[storage:ArrayObject:private] => Array
(
[time] => Derick Rethans
[iterate] => Marcus Börger
[test] => Sebastian Bergmann
)
)
Sur l’objet, on pourrait également effectuer
// une serialisation
$obj->serialize();
// ajouter des elements
$obj->offsetSet('enterprise', 'Ivo Jansch');
// supprimer un element par clef
$obj->offsetUnset('time');
SPL Observer
Depuis PHP 5.1, SPL offre deux interfaces pour implémenter Le Pattern Obsever: SplSubject et SplObserver. Le pattern Observer permet d’avoir une architecture modulaire en facilitant la communication entre les différents composants. Voici un lien (anglais) qui présente comment
implementer le Pattern Observer avec PHP et SPL.
Les iterateurs
Les iterateurs offrent une interface commune pour itérer sur n’importe quoi ;). On pourrait itérer sur des enregistrements résultats d’une base de données, des arbres xml, des répertoires, des tableaux classiques etc. SPL offre des iterateurs spécifiques selon la nature des besoins. L’avantage que les iterateurs offrent est bien évidemment reliée a la nature des données qui peut changer, du coup, on bénéficie des apports de l’objet: l’héritage et la surcharge.
Voici la liste supportée jusqu’a la version courante de PHP (5.3)
- AppendIterator
- ArrayIterator
- CachingIterator
- DirectoryIterator
- EmptyIterator
- FilesystemIterator
- FilterIterator
- GlobIterator
- InfiniteIterator
- IteratorIterator
- LimitIterator
- MultipleIterator
- NoRewindIterator
- ParentIterator
- RecursiveArrayIterator
- RecursiveCachingIterator
- RecursiveDirectoryIterator
- RecursiveFilterIterator
- RecursiveIteratorIterator
- RecursiveRegexIterator
- RecursiveTreeIterator
- RegexIterator
- SimpleXMLIterator
Exemples
FilterIterator
FilterIterator permet de filtrer les éléments d’une liste.
$animals = array('koala', 'kangaroo', 'wombat', 'wallaby', 'emu', 'NZ'=>'kiwi', 'kookaburra', 'platypus');
class AnimalsIterator extends FilterIterator
{
/* on passe un iterateur au constructeur puisqu'on etend FilterIterator */
public function __construct( Iterator $it )
{
parent::__construct( $it );
}
/*** check if key is numeric ***/
public function accept()
{
return is_numeric($this->key());
}
}
$cull = new AnimalsIterator(new ArrayIterator($animals));
foreach($cull as $key=>$value)
{
echo $key.' == '.$value.'
';
}
DirectoryIterator
DirectoryIterator permet d’itérer sur des répertoires tres facilement. Voici un exemple:
try
{
/*** class create new DirectoryIterator Object ***/
foreach ( new DirectoryIterator('./') as $Item )
{
echo $Item.'
';
}
}
/*** if an exception is thrown, catch it here ***/
catch(Exception $e)
{
echo 'No files Found!
';
}
Les exceptions
Les exceptions SPL offrent des templates pour des types communs d’exceptions. Les exceptions se divisent en deux types :
- les exceptions logiques
- BadFunctionCallException
- BadMethodCallException
- DomainException
- InvalidArgumentException
- LengthException
- LogicException
- les exceptions runtime.
- OutOfBoundsException
- OutOfRangeException
- OverflowException
- RangeException
- RuntimeException
- UnderflowException
- UnexpectedValueException
Les structures de données
SPL offre essentiellement des structures de données pour gérer une Liste chaînée, une Pile, un tas, un tableau a taille fixe ou un storage object.
- SplDoublyLinkedList
- SplStack
- SplQueue
- SplHeap
- SplMaxHeap
- SplMinHeap
- SplPriorityQueue
- SplFixedArray
- SplObjectStorage
Exemple
$heap = new SplMinHeap;
$heap->insert(6);
$heap->insert(2);
$heap->insert(7);
$heap->insert(5);
$heap->top();
while ($heap->valid())
{
echo $heap->key() . ': ' . $heap->current() . PHP_EOL;
$heap->next();
}
résultat
3: 2
2: 5
1: 6
0: 7
La gestion des Fichiers
La classe SplFileInfo offre une interface orientée objet de haut niveau qui présente des informations sur un fichier unique. Exemple :
// use the current file to get information from
$file = new SplFileInfo(dirname(__FILE__));
var_dump($file->isFile());
var_dump($file->getMTime());
var_dump($file->getSize());
var_dump($file->getFileInfo());
var_dump($file->getOwner());
Résultat
//output
bool(false)
int(1244760945)
int(408)
object(SplFileInfo)#2 (0) {
}
int(501)
Les fonctions SPL
La plus courante concerne l’autoload
- class_implements — Retourne la liste des interfaces implémentées par une classe donnée
- class_parents — Retourne les classes parents d’une classe donnée
- iterator_apply — Appelle une fonction sur chaque element d’un iterateur
- iterator_count — compte les éléments d’un iterateur
- iterator_to_array — Copie un iterateur dans un tableau
- spl_autoload_call — essaye tous les fonctions __autoload() enregistrées pour trouver une classe demandée
- spl_autoload_extensions — enregistre et retourne les extensions de fichiers par défaut pour spl_autoload
- spl_autoload_functions — retourne toutes les fonctions __autoload() enregistrées
- spl_autoload_register — enregistre une fonction comme une implémentation de __autoload()
- spl_autoload_unregister — des-enregistre une fonction de l’autoload
- spl_autoload — implémentation par defaut de __autoload()
- spl_classes — Retourne toutes les classes SPL disponibles
- spl_object_hash — Retourne un identifiant unique d’un objet.
Exemple :
interface foo {}
interface bar {}
class baz implements foo, bar {}
class example extends baz {}
var_dump(class_implements(new baz));
var_dump(class_implements(new example))
Résultat
array(2) {
["foo"]=>
string(3)
["bar"]=>
string(3)
}
array(2) {
["bar"]=>
string(3)
["foo"]=>
string(3)
}
Conclusion
Mon ami a aussi soulevé un point important concernant la documentation de SPL. La majorité des sections manquent d’exemples. Du coup, il avait souligné : “C’est pas connu ca.. Il n’y a même pas de documentation!”.
Voici quelques liens avec des exemples sur SPL :