Méthode __call() : appeler une méthode qui n’existe pas
PHP a fait un grand pas en avant en matière de programmation orientée objet avec sa version 5. Depuis cette version, il permet d’implémenter des méthodes au comportement prédéfini par PHP. Ces méthodes sont nommées « méthodes magiques », __call() est l’une d’entre elles.
Appeler une méthode qui n’existe pas
Prenons l’exemple d’une classe qui modélise un Manchot, que l’on instancie pour ensuite appeler sa méthode “voler”.
-
<?php
-
class Manchot {
-
}
-
$georges = new Manchot();
-
$georges->voler(‘Afrique’);
-
?>
Ce morceau de code vous lèvera une erreur. Vous ne le saviez peut-être pas mais les manchots ne peuvent pas voler :
Fatal error: Call to undefined method Manchot::voler() in /path/to/Apprendre-php/magic_methods.php on line 4.
Ce petit rappel morphologique vous permet surtout de voir la chose suivante : on ne peut pas appeler une méthode qui n’existe pas. Cependant PHP, grâce à la méthode magique __call(), va vous permettre de violer une loi élémentaire de la nature, à savoir faire voler un manchot ou plus généralement appeler une méthode qui n’a pas été déclarée dans votre classe.
Implémenter la méthode __call()
La méthode __call() prend deux paramètres. Le premier contient le nom de la méthode que vous avez cherché à appeler, le seconde contient les arguments que vous lui avez passés. Le listing ci-après présente le structure globale de cette méthode.
-
<?php
-
class MyObject {
-
public function __call($method, $arguments) {
-
// Code personnalisé à exécuter
-
}
-
}
-
?>
Maintenant reprenons l’exemple du Manchot.
-
<?php
-
class Manchot {
-
private function __call($method,$arguments) {
-
}
-
}
-
$george = new Manchot();
-
$george->voler(‘Afrique’);
-
?>
Quelques remarques :
Si vous avez rendu votre méthode __call() publique, vous aurez aussi la possibilité de l’appeler directement en faisant : $georges->__call(’voler’,'Afrique’); mais il y aura une petite différence. En appelant directement la méthode voler(), la variable $arguments sera un array stockant les différents arguments. A contrario, si vous passez par la méthode __call(), le second argument sera du type que vous voudrez.
A l’heure actuelle, il est impossible d’en faire de même avec des méthodes statiques, c’est quelque chose qui est désormais corrigée dans la version 5.3 de PHP qui vient tout juste de sortir en version alpha 1. Une méthode magique nommée « __callStatic() » permet, en PHP 5.3, d’appeler des méthodes statiques qui ne sont pas déclarées dans la classe.
Exemple concret : création d’un moteur de recherche
Vous vous dites que cela n’a pas grand intérêt, et pourtant avec l’exemple suivant vous devriez y voir un peu plus clair.
Nous allons tenter de recréer un moteur de recherche. Vous remarquerez que nous utilisons la classe SPDO présentée dans un précédent tutoriel et qui permet d’accéder à la base de données via l’extension native PDO.
-
<?php
-
class SearchEngine {
-
$query = ‘SELECT id FROM table’;
-
}
-
// Exécution de la requête SQL avec une classe PDO
-
$result = SPDO::getInstance()->query($query);
-
$return = $result->fetchAll(PDO::FETCH_ASSOC);
-
return $return;
-
}
-
}
-
?>
Comme vous pouvez le constater, ce moteur de recherche possède une méthode search() qui prend en paramètre un tableau des différentes conditions à appliquer à la requête effectuant la recherche. Ces conditions étant de la forme suivante : nomDuChamp= “valeur”.
Vous admettrez comme moi (j’espère !) que cette syntaxe n’est pas des plus pratiques, je ne me vois pas utiliser la requête de cette manière :
-
<?php
-
$mySearchEngine = new SearchEngine();
-
?>
Ce serait vraiment sympa de pouvoir faire $mySearchEngine->searchByName(’palleas’); par exemple, ou encore $mySearchEngine->searchByNameAndDate(’palleas’,'25/07/1987′); pas vrai ?
Et c’est là que l’on va pouvoir mettre en application la méthode __call().
-
<?php
-
class SearchEngine {
-
$query = ‘SELECT id FROM table’;
-
}
-
-
// Exécution de la requête SQL avec une classe PDO
-
$result = SPDO::getInstance()->query($query);
-
$return = $result->fetchAll(PDO::FETCH_ASSOC);
-
return $return;
-
}
-
-
-
public function __call($method, $args) {
-
for($i=0; $i < $nbCriterias; $i++) {
-
}
-
return $this->search($conditions);
-
}
-
return null;
-
}
-
}
-
?>
Voilà un morceau de code assez conséquent à digérer, nous allons donc le décortiquer étape par étape :
- Pour commencer, on vérifie que la méthode que l’on a cherché à appeler est une méthode dont le nom commence par « searchBy ». Cette étape n’est pas indispensable, nous appellerons ça une précaution : nous nous assurons ainsi de l’intuitivité du code.
- On récupère ce qu’il y a après searchBy, dans cet exemple : name
- Au cas ou nous aurions plusieurs Conditions, par exemple searchByNameAndDate, on récupère chacun des champs à tester, ici NameAndDate.
- Pour chacun des paramètres, on crée la condition, dans le cas de : $google->searchByNameAndDate(’palleas’,'25/07/1987′); on obtient un tableau avec name=«palleas » et date=«25/07/1987» que l’on va pouvoir passer en paramètre à la méthode search(), comme on en parlait plus haut.
Tutoriel posté en 3 heures sur apprendre-php, en 5 minutes sur mon blog. Le wysiwyg sauvera le monde ? Ah bah j’me marre tiens !
Dis plutôt que tu ne sais pas te servir du WYSIWYG :p Et puis c’est facile de le faire en 5 min quand il est déjà tout mis en forme sur Apprendre-PHP.com lol. Le copié / collé du code html c’est de la triche :p
+1 pour Hugo et balle au centre lol.
J’ai pas copié coller le code, juste le contenu, via notepad++ comme je l’ai fait pour AP ^^”