Comme beaucoup d’entre vous le savent déjà, PHP 7 sera le nom de la prochaine version majeure de PHP.
Peu importe vos sentiments sur ce sujet, PHP 7 est un fait, et il sortira cette année ! Nous sommes désormais entré dans la phase de « Feature freeze », c’est-à-dire que tout ajout de nouvelles fonctionnalités est bloqué, ce qui nous amène à la sortie de la prochaine version stable d’ici mi-juin.
Qu’est-ce que cela signifie pour vous ? Nous avons constaté une grande réticence de la part des hébergeurs web à passer sur les dernières versions 5.x. Alors est-ce qu’une nouvelle version majeure ne va pas apporter des gros problèmes de compatibilité avec les versions plus anciennes et ainsi rendre le processus encore plus lent ?
La réponse à cela est : cela dépend. Lisez la suite.
Un certain nombre de « problèmes extrêmes » de langage on été réparés. De plus, la performance et les réparations d’incohérences ont été les points d’attention majeurs de cette nouvelle version.
Voyons cela plus en détails.
Réparations d’incohérences
Malheureusement, les problèmes de type « aiguille dans une botte de foin » n’ont pas été réparés. Cependant, 2 problèmes majeurs ont été traité et vont apporter une certaine consistance interne et du côté des utilisateurs vraiment nécessaire.
Le plus grand (et plus invisible) est l’ajout d’un Abstract Syntax Tree (AST), en français Arbre Syntaxique Abstrait – une représentation intermédiaire du code pendant la compilation. Avec cela en place, nous sommes en mesure de réparer certains problèmes d’incohérences liés à des cas extrêmes, ainsi que d’ouvrir la voie à certains outils incroyables dans le futur, comme l’utilisation d’AST pour produire des opcodes plus performants.
Le deuxième, qui est l’introduction d’une Uniform Variable Syntax (en français Syntaxe de Variable Uniforme), pourra vous causer plus de problèmes. Cela résout de nombreuses incohérences à propos de comment les expressions sont évaluées. Par exemple, la possibilité d’appeler des « fermetures » assignées à des propriétés en utilisant ($object->closureProperty)(), ainsi que la possibilité d’attacher des appels statiques, comme cela :
class foo { static $bar = 'baz'; }
class baz { static $bat = 'Hello World'; }
baz::$bat = function () { echo "Hello World"; };
$foo = 'foo';
($foo::$bar::$bat)();
Cependant, certaines sémantiques sont également en train de changer. En particulier, les sémantiques lorsqu’on utilise les variable-variables/propriétés.
Avant PHP 7, $obj->$properties['name'] accèderait à la propriété dont le nom est dans la balise name du tableau $properties.
Ou pour être plus concis, si nous utilisons cette déclaration :
$obj->$properties['name']
Dans PHP 5.6, il serait interprété par :
$obj->{$properties['name']}
Et dans PHP 7 par :
{$obj->$properties}['name']
Alors que l’utilisation de variable-variables est généralement un cas extrême, et vu d’un mauvais œil, variable-properties sont beaucoup moins exceptionnels selon mon expérience. Vous pouvez cependant facilement contourner cela avec l’application de crochets (curly braces) (comme dans l’illustration ci-dessus) pour vous assurer le même comportement dans PHP 5.6 et PHP 7.
Performance
La meilleure raison de faire la mise à niveau vers PHP 7 est sa performance, apportée essentiellement par les changements introduits en tant que phpng. Les augmentations de performance peuvent en réalité assurer une adoption rapide, précisément pour les plus petits hébergeurs qui ne le ferait normalement pas, du fait qu’ils auront la possibilité d’héberger plus de clients avec le même matériel.
Dans l’état actuel des choses, en fonction de quelle référence vous choisissez, la performance de PHP 7 est équivalent à HHVM de Facebook, qui présente un compilateur Just In Time (JIT), en français Juste A Temps, qui compile le code PHP de haut en bas vers les instructions de la machine (s’il le peut).
PHP 7 ne présente pas un JIT, mais il a été beaucoup discuté. Ce n’est pas encore clair si l’ajout d’un JIT apporterait plus de gains de performance, mais il serait très intéressant de le constater si quelqu’un décide d’en créer un !
En plus de la performance, il devrait y avoir des gains de mémoire substantielle, étant donné que l’optimisation des structures de données internes est un des moyens essentiels grâce auquel les améliorations de performance ont été accomplies.
Modifications incompatibles avec les anciennes versions
Alors que les développeurs internes se sont efforcés de ne pas casser la compatibilité avec les versions plus anciennes, ce n’est pas toujours possible lorsqu’on fait évoluer le langage.
Cependant, comme les incompatibilités avec les versions antérieures introduites avec la Syntaxe de Variable Uniforme, la plupart d’entre elles sont mineures, comme la possibilité d’avoir une erreur fatale lorsqu’on essaye d’appeler une méthode sur un non-objet :
set_error_handler(function($code, $message) {
var_dump($code, $message);});
$var = null;
$var->method();echo $e->getMessage();
// Fatal Error: Call to a member function method() on nullecho "Hello World";
// Still runs
De plus, ASP et les tags scripts ont été supprimés, ce qui veut dire que vous ne pouvez plus utiliser <% et <%=, ou <script language="php”> (et ses tags relatifs respectifs, %>, et </script>).
D’autres changements plus importants apparaitront cependant dans la suppression de la fonctionnalité désapprouvée all.
Encore plus important, la suppression de l’habituelle extension d’expression compatible POSIX, ext/ereg (désapprouvée dans la 5.3) et l’ancienne extension ext/mysql (désapprouvée dans la 5.5).
Une autre modification mineure qui casse la compatibilité avec les anciennes versions est le refus de multiples clauses default dans un switch. Avant PHP 7, ce qui suit était autorisé :
switch ($expr) { default: echo "Hello World";
break;
default: echo "Goodbye Moon!";
break;
}
Cela aurait pour résultat de n’exécuter que ce dernier. Avec PHP 7, cela aurait pour résultat :
Erreur fatale : les déclarations de switch ne peuvent contenir qu’une clause default.
Nouvelles fonctionnalités
Nous acceptons à contrecœur les effets de l’incompatibilité avec les versions antérieures. Nous apprécions la performance. Mais nous nous réjouissons des nouvelles fonctionnalités ! Les nouvelles fonctionnalités représentent le côté fun de chaque version – et PHP 7 n’est pas radin en nouvelles fonctionnalités.
Scalar Type Hints et Return Types
Je vais commencer par la modification la plus controversée qui ait été ajoutée à PHP 7 : Scalar Type Hints. L’ajout de cette fonctionnalité a impliqué un vote qui a pratiquement réussi. Mais l’auteur a ensuite arrêté le développement de PHP pour de bon (retirant le RFC). S’en sont ensuite suivi de nombreux RFC pour des ajouts concurrents, et tout un tas de luttes publiques qui se sont finalement terminées (efficacement) par l’acceptation du RFC original.
Pour vous, en tant qu’utilisateurs finaux, ce que cela veut dire est que vous pouvez désormais utiliser les type-hint avec des scalar types. Spécifiquement : int, float, string, et bool. Par défaut les type-hints ne sont pas strict, ce qui veut dire qu’ils vont forcer le type original avec le type spécifié par le type-hint. Cela signifie que si vous passez int(1) dans une fonction qui requiert un float, il deviendra float(1.0). Le fait de passer float(1.5) dans une fonction qui requiert un int, deviendra int(1).
Voici un exemple :
function sendHttpStatus(int $statusCode, string $message) {
header('HTTP/1.0 ' .$statusCode. ' ' .$message);
}
sendHttpStatus(404, "File Not Found");
// integer and string passed
sendHttpStatus("403", "OK");
// string "403" coerced to int(403)
De plus, vous pouvez activer le strict mode en plaçant declare(strict_types=1) ; au début de n’importe quel fichier, ce qui aura pour effet d’assurer que toute fonction appelée dans ce fichier adhère strictement aux types spécifiés. Strict est déterminé par le fichier dans lequel l’appel d’une fonction est réalisé, pas le fichier dans lequel la fonction est définie.
Si une incompatibilité de type-hint survient, une Catchable Fatal Error est lancée :
<?php
declare(strict_types=1);
// must be the first line
sendHttpStatus(404, "File Not Found");
// integer and string passed sendHttpStatus("403", "OK");
// Catchable fatal error: Argument 1 passed to sendHttpStatus() must be of the type integer, string given
En outre, PHP 7 supporte également les Return Type Hints, qui supportent tous les mêmes types que les arguments. Ceux-ci suivent la même syntaxe comme hack, en suffixe à l’argument parenthèse avec une colonne suivie du type :
function isValidStatusCode(int $statusCode): bool {
return isset($this->statuses[$statusCode]);
}
Dans cet exemple le « : bool » indique que la fonction va retourner un boolean.
La même règle qui s’applique aux type-hints s’applique aux returned type hints pour le strict mode.
Opérateur de comparaison combinée (Combined Comparison Operator)
L’ajout que je préfère personnellement dans PHP 7 est l’ajout de Combined Comparison Operator, <=>, autrement connu en tant qu’opérateur spatial. Je ne suis peut être pas objectif étant donné que j’ai écrit le patch initial et que j’ai influencé le nom (T_SPACESHIP), mais cet opérateur reste un ajout très plaisant au langage, en étant complémentaire avec les opérateurs greater-than et less-than.
Cela fonctionne efficacement comme strcmp(), ou version_compare(), renvoyant -1 si l’opérande gauche est plus petit que le droit, 0 s’ils sont égaux, et 1 si le gauche est plus grand que le droit. La différence majeure étant que cela peut être utilisé sur n’importe lequel des deux opérandes, pas seulement pour les strings, mais aussi les integers, floats, arrays, etc.
L’usage le plus commun pour cet opérateur est le tri de rappels :
// Pre Spacefaring^W PHP 7
function order_func($a, $b) {
return ($a < $b) ? -1 : (($a > $b) ? 1 : 0);
}
// Post PHP 7
function order_func($a, $b) { return $a <=> $b; }
Consulter notre comparatif d'hébergeurs web supportant PHP