Demander un devis gratuit

Très facile

En PHP, si vous travaillez avec des classes, vous aurez parfois besoin de vérifier si une méthode existe avant de l’appeler. Pour ça, il y a deux solutions : la fonction method_exists ou la fonction is_callable. Mais quelle différence entre les deux ? Quelles fonctions utiliser et dans quelle situation ?

Ce petit tutoriel théorique n’est pas très compliqué à comprendre, mais il vaut mieux que vous sachiez déjà utiliser des classes en PHP. 😊

Quand faut-il vérifier qu’une méthode de classe existe ?

Quand on travaille avec un framework ou un CMS, notre site internet dépend de ce système dont nous ne contrôlons pas les changements. Sachant cela, pour éviter de passer des heures à essayer de comprendre pourquoi un plugin ne fonctionne plus, il peut être très utile de s’assurer que les classes qu’on utilise existent, et mieux encore, que les méthodes que l’on appelle sont toujours là ! 😏

Pour ça, le PHP possède deux fonctions : method_exists et is_callable, mais si l’une est plus parlante que l’autre, vous allez voir que ce n’est pas toujours celle qu’il vaut mieux utiliser… 😇 Pour mieux comprendre, commençons par examiner les deux fonctions en question.

La fonction method_exists en PHP

La première est method_exists() et vous l’aurez compris, elle retourne true si la méthode d’une classe demandée existe, sinon elle retourne false. Voici un exemple d’utilisation qui sera plus parlant :

class MaClass { 
    public function laMethode() { }
    public function lautreMethode() { }
}
if( method_exists("MaClass", "laMethode") ) {
    echo "Bravo l'ami !";
}
//si j'appelle une méthode qui n'existe plus dans la classe...
var_dump( method_exists("MaClass", "lancienneMethode") ); //retournera bool(false) 

//on peut aussi instancier la classe avant, ça marche aussi 
$maClass = new MaClass();
var_dump( method_exists($maClass, "lautreMethode") ); //retournera bool(true)

La condition IF dans cet extrait de code affichera « Bravo l’ami ».

Petit exemple pratique de method_exists

Cette technique de vérification est la plus utilisée et pourtant, quand on y pense, ce n’est pas la meilleure solution dans une grande majorité des cas 🙄. En effet, une méthode de classe n’est pas forcément publique, et donc elle n’est pas systématiquement utilisable par un composant de type plugin 😕. Mais testons quand même : 😇

//réécrivons notre classe qui sert d'exercice
class MaClass {
    protected function laMethode() { //la méthode n'est plus publique !
        return "Bravo l'ami !";
    }
    public function lautreMethode() { }
}

//testons à présent !
$maClass = new MaClass();
//on vérifie avant d'aller plus loin ^^
var_dump( method_exists($maClass, "laMethode") ); // renvoi bool(true), OK !

//après la théorie, la pratique !
if( method_exists($maClass, "laMethode") ) {
    $do = $maClass->laMethode();
} else {
    echo "La méthode 'MaClass:laMethode()' n'existe pas ! (ou on l'a supprimé pour t'embêter).";
}

A votre avis, que va afficher cette condition ? 😊

  1. Elle n’affichera rien.
  2. Elle renverra un message d’erreur PHP.
  3. Elle affichera « Bravo l’ami ! « 
  4. Elle affichera « La méthode ‘MaClass:laMethode()’ n’existe pas ! (ou on l’a supprimé pour t’embêter). »

Non, ne lisez pas plus loin, répondez à la question avant ! 😝

Vous pensez avoir trouvé la bonne réponse ? C’est ce qu’on va voir 😎. Tout d’abord, ce code ne peut pas afficher « Bravo l’ami ! », et ce tout simplement parce que nous stockons ce que renvoi l’appel de la méthode de classe dans la variable $do. Aucune ligne ne permet d’afficher ce que contient $do, donc ceux qui ont répondu réponse 3, vous avez -2 ! (oui, je sais, ça fait mal 😈).

Alors, me diriez-vous, ce code n’affichera rien ! Et bien… non 😕. OK, dans ce cas il affichera que la méthode n’existe pas ! Et bien… non plus 🙁. Ceux qui ont répondu réponse 1 ou 4 ont perdu également, vous avez -1 😈. La bonne réponse c’est la deuxième 🤓. Ce code affichera une erreur, et une de celle qu’on n’aime pas voir 😒 :

Fatal error: Call to protected method MaClass::laMethode() from context '' in /file.php on line 16

Vous voyez, on a comme un problème 😟. Pourquoi ? Parce que la fonction method_exists se contente de vérifier qu’une méthode de classe existe, elle ne tient pas compte de sa portée ! 😇 Dans notre exemple, MaClass:laMethode() a justement subi ce changement. Ainsi, si notre condition fonctionnait parfaitement avant, ce n’est plus le cas maintenant.

En fait, ce code est correct mais dans ce cas précis, la fonction method_exists ne nous aide pas du tout 🙁. PHP renvoi une erreur qui va bloquer toutes les instructions qui suivent, et c’est le comble car c’est justement ce qu’on cherche à éviter ! 🙄

La fonction is_callable en PHP

Alors comment faire ?! 🤔 Et bien c’est là que la fonction PHP is_callable arrive à votre secours 😷. Cette fonction porte bien son nom car elle permet de savoir si une méthode peut être appelée. Ainsi, tout comme la fonction empty() qui doit vérifier que la variable existe pour savoir si elle est vide, la fonction is_callable doit d’abord vérifier que la méthode existe pour pouvoir l’appeler.

Réécrivons notre condition et testons ! :

//rappel : MaClass:laMethode a une portée "protected"
if( is_callable(array('MaClass', "laMethode")) ) { 
    echo $maClass->laMethode();
} else {
    echo "Désolé l'ami...";
}

Ce code affichera « Désolé l’ami… » car is_callable a renvoyé false parce que la méthode demandée n’est pas « appellable ». Ainsi, on évite d’afficher un message d’erreur qui bloquerait notre programme. 😊

Il est intéressant de préciser que is_callable prend en compte les méthodes magiques __call et __callStatic, ce que method_exists ne sera pas capable de détecter. 😉

 

Quelle différence entre method_exists et is_callable ?

Après un tel discours, vous devez penser que la fonction method_exists ne sert pas à grand chose. Vous avez tord si vous en êtes arrivé à cette conclusion. Croyez-moi, ces deux fonctions ont leur utilité.

Déjà, il est évident que cela ne sert à rien de les utiliser ensemble 😇 car is_callable va vérifier si la méthode existe pour savoir si elle peut être appelée. Mais il faut savoir que method_exists est quand même plus rapide que is_callable, et c’est parfois pour cette seule raison que les développeurs l’utilisent 😎. Utiliser is_callable rendra votre code plus fiable, mais c’est au prix de quelques milisecondes supplémentaires.

Ceci dit, contentez-vous d’utiliser method_exists si vous n’avez pas besoin d’appeler la méthode, mais juste de savoir qu’elle est bien déclarée 😊. Exemple :

if(method_exists('Newsletter', 'register')) {
    /* Je sais qu'une classe "Newsletter" permet l'inscription, alors 
    je peux afficher le formulaire d'inscription à la newsletter. */
} 

Vous l’aurez compris, method_exists permet aussi de vérifier qu’une classe existe. C’est logique puisque pour savoir si une méthode est déclarée, il faut d’abord déterminer si la classe l’est aussi. 😏 Il en est de même avec la fonction is_callable, mais il vaut mieux l’utiliser quand on a besoin d’appeler une méthode qui peut ne pas être disponible.

Petit conseil : éviter d’instancier une classe pour laquelle vous souhaitez vérifier qu’une méthode existe, car les deux fonctions renverront une erreur PHP si la classe est abstraite. 🤓

 


🚀PHP

Articles associés

Rédigé le et modifié le

Soyez le premier à réagir !

Des questions ? Un avis ?

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Expérience
+ de 6 ans d'expérience
Garantie
Garantie offerte
France
Made in France