PHP dans sa version 5 introduisait un modèle objet plus robuste que dans sa version 4 lui permettant de quasiment rivaliser avec des langages plus évolués comme java ou c/c++.
C’est quoi une interface ?
En programmation objet, une interface permet de définir les méthodes publiques qu’une classe doit implémenter. Le fait qu’une classe implémente une interface l’oblige à disposer au minimum des méthodes décrites dans cette interface au quel cas une erreur fatale sera levée.
Cela permet de définir une API (Application Programming Interface) qu’un composant pourra utiliser.
Les interfaces définies par PHP5
PHP5 propose différentes interfaces permettant de répondre à des demandes assez répandues : compter, sérialiser, traverser, itérer, …
Pour présenter les interfaces proposées par PHP5, je baserai mes exemples sur la classe suivante :
class myObject {
protected $_data = array( 'un', 'deux', 'trois' );
}
Cette classe implémentera au fur et à mesure de l’article les interfaces présentées.
Countable : une interface pour compter
Objectif : permettre à un objet d’être utilisé avec la fonction count() (ou sizeof())
La signature de l’interface Countable est la suivante :
interface Countable {
public function count();
}
Noter que le système force la valeur de retour en tant qu’entier
Notre classe implémentant l’interface Countable devient :
class myObject implements Countable {
// code précédent
public function count() {
return count( $this->_data );
}
}
Utilisation :
$o = new myObject(); echo count( $o ); // Affiche 3
Serializable : linéarisation personnalisée d’un objet
Objectif : personnaliser la linéarisation/délinéarisation d’un objet.
Par défaut, lorsqu’on linéarise un objet avec serialize(), toutes les propriétés de cet objet sont traitées. On peut vouloir effectuer un traitement personnalisé lorsqu’un objet est passé à la fonction serialize() (et donc un traitement personnalisé pour serialize()). C’est ce que permet de faire l’interface Serializable dont la signature est la suivante :
interface Serializable {
public function serialize ();
public function unserialize ( $serialized );
}
Notre classe implémentant l’interface Serializable devient :
class myObject implements Serializable, Countable {
// code précédent
public function serialize() {
return serialize( $this->_data );
}
public function unserialize( $serialized ) {
$this->_data = unserialize( $serialized );
}
}
Utilisation :
$o = new myObject();
$s = serialize( $o );// retourne C:8:"myObject":50:{a:3:{i:0;s:2:"un";i:1;s:4:"deux";i:2;s:5:"trois";}}
$o2 = unserialize( $s); // $o2 est un nouvel objet myObject
ArrayAccess : mon objet est un tableau !
objectif : accéder à mon objet comme si c’était un tableau (comme par exemple $o[0]).
la signature de l’interface ArrayAccess est la suivante :
interface ArrayAccess {
public function offsetExists( $offset );
public function offsetGet( $offset );
public function offsetSet( $offset, $value );
public function offsetUnset( $offset );
}
Notre classe implémentant l’interface ArrayAccess devient :
class myObject implements ArrayAccess, Serializable, Countable {
// code précédent
public function offsetExists( $offset ) {
return isset( $this->_data[$offset] );
}
public function offsetGet( $offset ) {
return isset( $this->_data[$offset] ) ? $this->_data[$offset] : null;
}
public function offsetSet( $offset, $value ) {
$this->_data[$offset] = $value;
}
public function offsetUnset( $offset ) {
unset( $this->_data[$offset] );
}
}
Utilisation :
$o = new myObject(); var_dump( isset( $o[0] ) ); // true var_dump( isset( $o['un'] ) ); // false $o['un'] = 1; var_dump( isset( $o['un'] ) ); // true
Iterator : itérer un objet
Objectif : personnaliser le parcours d’un objet en utilisant une boucle comme foreach()
Par défaut, lorsqu’on parcours un objet avec foreach(), on itère sur les propriétés publiques de l’objet. Dans certains cas, on préférera gérer soit même cette itération. C’est ce que permet de réaliser l’interface Iterator dont la signature est la suivante :
Iterator extends Traversable {
public function current();
public function key();
public function next();
public function rewind();
public function valid();
}
Notre classe implémentant l’interface Iterator devient :
class myObject implements Iterator, ArrayAccess, Serializable, Countable {
// code précédent
public function current() {
return current( $this->_data );
}
public function key() {
return key($this->_data );
}
public function next() {
return next( $this->_data );
}
public function rewind() {
return reset( $this->_data );
}
public function valid() {
return (bool)current( $this->_data );
}
}
Utilisation :
$o = new myObject();
foreach( $o as $key => $value ) {
echo "$key =>$value \n";
}
/* Affiche
* 0=>un
* 1=>deux
* 3=>deux
*/
La classe MyObject terminée
La classe ainsi créée est la suivante :
class myObject implements Iterator, ArrayAccess, Serializable, Countable {
protected $_data = array( 'un', 'deux', 'trois');
public function count() {
return count( $this->_data );
}
public function serialize() {
return serialize( $this->_data );
}
public function unserialize( $serialized ) {
$this->_data = unserialize( $serialized );
}
public function offsetExists ( $offset ) {
return isset( $this->_data[$offset] );
}
public function offsetGet ( $offset ) {
return isset( $this->_data[$offset] ) ? $this->_data[$offset] : null;
}
public function offsetSet ( $offset, $value ) {
$this->_data[$offset] = $value;
}
public function offsetUnset ( $offset ) {
unset( $this->_data[$offset] );
}
public function current() {
return current( $this->_data );
}
public function key() {
return key($this->_data );
}
public function next() {
return next( $this->_data );
}
public function rewind() {
return reset( $this->_data );
}
public function valid() {
return (bool)current( $this->_data );
}
}
Pour être mieux exploitable, la classe devrait posséder quelques méthodes supplémentaires : un constructeur acceptant un paramètre pour initialiser la propriété $_data, un getter et un setter et elle serait pleinement fonctionnelle.
Pour les plus curieux d’entre-vous, sachez que cette classe et relativement assez proche de la classe ArrayObject fournie par PHP5. Elle permet en effet d’utiliser un objet quasiment comme un tableau, ou, d’un autre point de vue, de remplacer le fonctionnement procédural des tableaux en fonctionnement objet.
L’équipe de développement de
Tout juste 1 semaine 1/2 après la version 2.8.1, Wordpress publie la version 2.8.2 afin de corriger une faille XSS.