Utilisation des interfaces en PHP
Date de publication : 12.03.2006
Par
Alain Sahli
Cet article traite l'utilisation des interfaces en PHP. Ce dernier n'est pas destiné à des débutants et de bonnes bases en POO sont requises pour la
compréhension du code fourni tout au long de l'article.
I. Introduction
II. Les interfaces
II-A. Création
II-B. Implémentation
II-B-1. Implémentation d'une interface
II-B-2. Implémentation de plusieurs interfaces
III. Exemple d'utilisation
III-A. Pré-requis
III-B. Arborescence de l'exemple
III-C. L'interface IAnimal.php
III-D. Les classes
III-D-1. La classe Zoo
III-D-2. La classe Lion
III-D-3. La classe Gazelle
III-E. Le fichier autoload.inc.php
III-F. Résultat final
IV. Les interfaces existantes
V. Conclusion
I. Introduction
Contrairement à PHP4, PHP5 permet de gérer les interfaces. Ces-dernières permettent de créer un modèle, que les classes qui l'implémentent
doivent respecter. On peut comparer une interface à une fiche éléctrique, elle définit un standard de "connexion" sans savoir quelles types
d'appareils vont venir s'y connecter. Les interfaces sont très pratiques lorsque plusieurs personnes développent un même projet, ou
lorsqu'on développe un site modulaire.
II. Les interfaces
Une interface regroupe toutes les méthodes qu'une classe doit contenir pour l'implémenter. Ce procédé permet d'appeler les méthodes d'une
classe sans se soucier de l'existence de ces dernières. Les méthodes déclarées dans une interface ne peuvent être de type private étant
donné que l'on définit dans une interface les méthodes que l'on pourra appeler lors de l'instanciation. Déclarer des fonctions private
reviendrait à imposer un style de traitement dans la classe alors que ce n'est pas le but.
II-A. Création
Pour créer une interface on procède de la même manière que lorsqu'on crée une classe mais à la place d'utiliser le mot clé "class",
on utilise le mot clé "interface".
Création d'une interface |
<?php
interface IMonInterface
{
public function titi($ name );
public function toto($ firstName );
}
interface IMonInterfaceStatic
{
static function staticTiti($ name );
static function staticToto($ firstName );
}
?>
|
II-B. Implémentation
L'implémentation se fait de la même manière que l'héritage, sauf que l'on utilise le mot clé "implements". Une classe peut
implémenter plusieurs interfaces. Quand une classe implémente une interface, cela signifie que toutes les méthodes présentes dans
l'interface le sont également dans la classe!
 |
Si une classe implémente une interface et ne contient pas toutes les méthodes déclarées dans celle-ci, une erreur sera générée!
|
II-B-1. Implémentation d'une interface
Comme vous pouvez le voir ci-dessous j'ai simplement déclaré une classe "MaClasse" qui implémente l'interface "IMonInterface".
Ensuite il a fallu créer toutes les méthodes présentent dans l'interface.
Implémentation d'une interface |
<?php
require_once ' IMonInterface.php ' ;
class MaClasse implements IMonInterface
{
public function titi($ name )
{
echo $ name ;
}
public function toto($ firstName )
{
echo $ firstName ;
}
}
?>
|
II-B-2. Implémentation de plusieurs interfaces
Lorsqu'une classe implémente plusieurs interfaces, il faut les séparer par une ',' (virgule). La classe ci-dessous implémente
deux interfaces; il a donc fallu créer toutes les méthodes contenues dans l'interface "monInterface" ainsi que toutes les méthodes
présentes dans l'interface "monInterfaceStatic".
Implémentation de plusieurs interfaces |
<?php
require_once ' IMonInterface.php ' ;
require_once ' IMonInterfaceStatic.php ' ;
class MaClassMultiInterfaces implements IMonInterface, IMonInterfaceStatic
{
public function titi($ name )
{
echo $ name ;
}
public function toto($ firstName )
{
echo $ firstName ;
}
static function staticTiti($ name )
{
echo $ name ;
}
static function staticToto($ firstName )
{
echo $ firstName ;
}
}
?>
|
 |
Lors de l'implémentation de plusieurs interfaces, il faut faire attention de ne pas créer les mêmes noms de méthodes dans plusieurs
interfaces!
|
III. Exemple d'utilisation
Nous sommes maintenant capables de créer et d'implémenter des interfaces. Réalisons un exemple concret.
Imaginons une classe Zoo.php qui va devoir afficher un inventaire de tous ses animaux avec leur nourriture préférée. Nous savons que la
classe Zoo.php devra appeler trois méthodes: getAnimal(), getNourriture() et getNom() mais nous ne savons pas combien d'animaux il y aura.
Pour cela nous allons créer une interface IAnimal que chaque animal devra implémenter pour pouvoir entrer dans le Zoo.
III-A. Pré-requis
Pour réaliser cet exemple il est nécessaire d'avoir au minimum la version 5 de PHP.
 |
Les essais on été fait avec la version 5.2.0
|
III-B. Arborescence de l'exemple
Ci-dessous l'arborescence du projet:
index.php
/class
Gazelle.php
Lion.php
Zoo.php
/interface
IAnimal.php
/inc
autload.inc.php
III-C. L'interface IAnimal.php
Comme je l'ai expliquer dans la partie "Exemple d'utilisation" toutes les classes d'animaux devront pouvoir nous retourner l'animal
concerné, la nourriture qu'il mange ainsi que sont nom. Nous allons créer ces trois méthodes dans notre interface.
Interface IAnimal.php |
<?php
interface IAnimal
{
public function getAnimal();
public function getNourriture();
public function getName();
}
?>
|
III-D. Les classes
Pour illustrer cet exemple nous allons donc créer 3 classes, une classe Zoo qui est la classe mère et deux classes d'animaux (Lion et
Gazelle).
III-D-1. La classe Zoo
Class Zoo |
<?php
class Zoo
{
public function showAnimals()
{
$ animaux = array ();
$ animaux [ ] ($ animaux , new Lion(' Bobby ' ));
$ animaux [ ] ($ animaux , new Gazelle(' Petra ' ));
foreach ($ animaux as $ animal )
{
echo ' Animal: ' . $animal ->getAnimal (). ' <br/> ' ;
echo ' Nom: ' . $animal ->getName (). ' <br/> ' ;
echo ' Nourriture préférée: ' . $animal ->getNourriture (). ' <br/><br/> ' ;
}
}
}
?>
|
III-D-2. La classe Lion
Classe Lion |
<?php
require_once ' interface/IAnimal.php ' ;
class Lion implements IAnimal
{
private $ name ;
public function __construct ($ argName )
{
$this ->name = $ argName ;
}
public function getAnimal()
{
return ' Lion ' ;
}
public function getNourriture()
{
return ' Viande ' ;
}
public function getName()
{
return $this ->name ;
}
}
?>
|
III-D-3. La classe Gazelle
Classe Gazelle |
<?php
require_once ' interface/IAnimal.php ' ;
class Gazelle implements IAnimal
{
private $ name ;
public function __construct ($ argName )
{
$this ->name = $ argName ;
}
public function getAnimal()
{
return ' Gazelle ' ;
}
public function getNourriture()
{
return ' Herbe ' ;
}
public function getName()
{
return $this ->name ;
}
}
?>
|
III-E. Le fichier autoload.inc.php
Ce fichier contient la fonction __autoload() qui est appelée lorsqu'on instancie une classe et que le fichier de classe n'est pas
inclu. Cette fonction va donc s'occuper de charger les classes.
autoload.inc.php |
<?php
function __autoload ($className )
{
require_once(' class/ ' . $className . ' .php ' );
}
?>
|
III-F. Résultat final
Maintenant que tous ces fichiers sont créés il nous faut encore créer l'index.php qui va afficher les animaux du zoo.
Fichier index.php |
<?php
require_once ' inc/autoload.inc.php ' ;
$Zoo = new Zoo();
$Zoo ->showAnimals ();
?>
|
Et voici ce que sa affiche:
Animal: Lion
Nom: Bobby
Nourriture préférée: Viande
Animal: Gazelle
Nom: Petra
Nourriture préférée: Herbe
|
IV. Les interfaces existantes
Peut être l'aurai vous déjà remarqué, lorsqu'on utilise la fonction get_declared_interfaces() PHP va vous retourner le tableau suivant:
Array
(
[ 0] = > Traversable
[ 1] = > IteratorAggregate
[ 2] = > Iterator
[ 3] = > ArrayAccess
[ 4] = > reflector
[ 5] = > RecursiveIterator
[ 6] = > SeekableIterator
}
|
Ce sont des interfaces prédéfinies par PHP. Etant donné qu'un exemple est mille fois plus parlant que des lignes de texte je vais vous donner
un exemple concret. Imaginez que vous aimeriez avoir un tableau qui ne supporte pas les clés de type 'string'. Vous savez que c'est impossible
car PHP est très souple au niveau des tableaux et il accepte les clés de type 'string'.
Pour remédier à ce problème, nous allons créer notre propre classe de gestion de tableau qui ne va accepter que les clés de type 'int'.
Gestion de tableau |
<?php
class MyArray implements ArrayAccess
{
protected $ array = array ();
function offsetSet($ offset , $ value )
{
if (! is_numeric($ offset ))
{
throw new Exception (' Clé invalide! ' );
}
$this ->array [ $ offset ] = $ value ;
}
public function offsetGet($ offset )
{
return $this ->array [ $ offset ] ;
}
public function offsetUnset($ offset )
{
unset($this ->array [ $ offset ] );
}
public function offsetExists($ offset )
{
return isset($this ->array [ $ offset ] );
}
}
$myArray = new MyArray();
$ myArray [ ' a ' ] = 10 ;
$ myArray [ 3 ] = 12 ;
?>
|
Les quatres méthodes qui sont présentes dans la classe MyArray sont obligatoires! Ce n'est pas moi qui ai choisi de les implémenter, c'est
l'interface ArrayAccess qui m'oblige à les implémenter pour garantir le bon fonctionnement de mon tableau. Chaque interface a ces propres
fonctions, je vous laisse les découvrir ici :
SPL.
V. Conclusion
A première vue, les interfaces ont l'air inutiles mais lorsqu'on développe de gros projets on se rend vite compte qu'elles sont indispensables!
Mais il faut tout de même faire attention à ne pas utiliser des interfaces juste pour en utiliser! C'est là tout l'art de la conception objet.


Les sources présentées sur cette page sont libres de droits
et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation
constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ©
2007 Alain Sahli. Aucune reproduction, même partielle, ne peut être
faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc.
sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à
trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.