Une des grandes forces de PHP – qui est aussi, hélas !, une de ses plus grandes faiblesses – est l’absence de typage fort comme c’est le cas en Java, en C#, C++ ou dans bien d’autres langages dits « orientés objet ». PHP s’occupe de faire les conversions de type qui l’arrangent, notamment lorsque l’on effectue des comparaisons entre des types différents (voilà pourquoi les opérateurs stricts ont été introduits qui comparent en valeur et surtout en type). Tout ça est décidé de façon dynamique au runtime (à l’exécution, en bon français) et non pas de façon statique, à la compilation.
Depuis les versions 5.X, on pouvait déjà typer des paramètres de fonction avec certains types non-scalaires : objet depuis 5.0 et array depuis 5.1 (et callable par la suite, mais passons…). Dans des temps reculés (avant 5.X), on n’avait pas trop le choix:
function peuimporte ($param, $reparam) {
var_dump($param);
var_dump($reparam);
}
L’appel de cette fonction pouvait se faire avec des arguments de divers types : entiers, flottants, tableaux, objets, chaînes de caractères…Pour faire court, on pouvait un peu passer tout et (surtout) n’importe quoi !
peuimporte (1, 1.23);
peuimporte ("a", 1);
peuimporte (array(), new StdClass());
Un type scalaire est un type qui ne contient qu’une valeur à la fois: un entier, une chaine de caractères, un booléen etc. Un type non scalaire peut contenir plusieurs valeurs; un tableau, un objet…ce sont des types composites – ou des collections de valeurs.
Depuis PHP 5.1 disais-je, on pouvait forcer le typage des paramètres des fonctions avec des types non scalaires comme un tableau:
function peuimporte (Array $param) {
// faites ce que bon vous semble
}
ou bien un objet d’un type particulier:
class UnTypeAuPif {}
function peuimporte (UnTypeAuPif $param) {
// faites ce que bon vous semble
}
ou encore d’un super-type, comme une interface:
interface Bidon {}
class UnTypeAuPif implements Bidon {}
class UnAutreTypeAuPif implements Bidon {}
function peuimporte (Bidon $param) {
// faites ce que bon vous semble
}
Il suffit alors de passer en argument une instance qui ne se conforme pas aux spécifications que constitue la signature de notre fonction et VLAN!
Catchable fatal error: Argument 1 passed to peuimporte() must be an instance of UnTypeAuPif, instance of stdClass given
Ici j’ai tenté de réaliser l’invocation suivante :
peuimporte(new StdClass);
J’ai allégrement violé le contrat qui me lie à cette fonction et qui stipule qu’il ne faut passer que des instances de UnTypeAuPif (dans le premier exemple).
Depuis mars 2015 (et une RFC qui a fait l’objet d’un débat, puis d’un vote) il est donc prévu que PHP 7 nous donne la possibilité de spécifier des types scalaires pour nos arguments…ENFIN ! Il deviendra donc possible d’écrire:
function peuimporte (int $param) {
// faites ce que bon vous semble
}
ou bien:
function peuimporte (string $param) {
// faites ce que bon vous semble
}
ou encore:
function peuimporte (float $param) {
// faites ce que bon vous semble
}
Le fait de passer en argument d’un appel une variable du mauvais type provoque une erreur fatale, par exemple:
Fatal error: Uncaught TypeError: Argument 1 passed to peuimporte() must be of the type float, string given
Pour activer ce typage strict sous PHP 7, il faut utiliser declare que l’on connait depuis 5.3 et qui sert lors de la compilation du fichier. Ce language construct sera placé en tout début de fichier (sous peine de provoquer une erreur fatale) comme suit:
declare(strict_types = 1);
function peuimporte (float $param) {
// TODO
}
peuimporte(1.23);
Notez que le mode bloc, originellement proposé pour strict_types
, a été interdit dans PHP 7. Cette fonctionnalité n’est pas forcée par défaut, nul risque donc de BC break dans le code existant. L’aspect lâche du typage en PHP reste encore la règle (pour combien de temps ?), ce qui continuera de faciliter l’intégration des gens qui ne sont pas des développeurs de formation.
Pour les développeurs qui viennent du monde des langages fortement typés et qui se sentent frustrés par le typage faible de PHP, c’est une bonne nouvelle et sans doute une raison de plus de cesser de prendre PHP pour un langage de seconde zone.
Il me tarde que PHP 7 fasse l’objet d’une release officielle pour bénéficier de cette tant attendue fonctionnalité !
Testé avec un PHP7 bêta compilé sur Debian Jessie…et approuvé !