Quoi de neuf dans PHP 8 : tout ce que vous devez savoir !

Publié: 2021-01-06

Nous prendrons contact avec PHP8 le 26 novembre 2020 , et certainement, il y a beaucoup d'écrits concernant les fonctionnalités à venir dans cette version appréciée.

PHP 8

Comme il s'agit d'une version majeure, il y aura des changements de rupture et de nouvelles fonctionnalités ainsi qu'il est important d'être conscient de ce que tout change. Cela facilitera la réflexion sur la manière dont PHP8 affectera vos applications et sur les actions à entreprendre pour vous assurer de pouvoir effectuer une mise à niveau facilement et sans incident.

Nous avons passé en revue quelques-uns des changements les plus considérables pour déterminer ce que nous allons obtenir dans la prochaine version de PHP et ce qui mérite d'être critiqué.

commençons par la vue d'ensemble !

Présentation de PHP8

Comme mentionné ci-dessus, PHP 8 introduit un ensemble de nouvelles fonctionnalités, améliorations, fonctions et dépréciations du langage. Parmi toutes ces fonctionnalités, la fonctionnalité la plus discutée est le compilateur JIT. Cependant, les fonctionnalités d'amélioration des performances telles que JIT méritent la vedette, mais les améliorations syntaxiques devraient avoir plus d'un véritable succès pour les praticiens PHP, dirions-nous, "au moins à court terme".

Une histoire de changement

Quelques modifications PHP sont proposées, débattues, implémentées et approuvées en peu de temps. Ils sont populaires, non controversés et ont une méthode naturelle pour les mettre en œuvre.

Et après cela viennent ceux qui sont essayés, échouent et reviennent plusieurs fois avant que nous les acceptions finalement. Parfois, la mise en œuvre prend beaucoup de temps à régler, et parfois l'idée elle-même n'est qu'à moitié cuite, et parfois la communauté elle-même ne s'est pas encore réchauffée à l'idée - "ce n'est pas encore le moment".

Les crédits entrent carrément dans la catégorie type. Ils ont été proposés pour la première fois en 2016 pour PHP 7.1. Cependant, ils ont rencontré une résistance obstinée et ont perdu le vote d'acceptation par une forte marge. Maintenant, quatre ans plus tard, une proposition assez similaire, quoique légèrement réduite, a été présentée avec un seul dissident. C'est évidemment une idée dont l'heure est certainement venue !

Quels sont les problèmes avec l'ancien code ?

Comme PHP 8 est une énorme nouvelle version, nous devrions nous attendre à ce que l'ancien code ne soit plus compatible. Cependant, la majorité des modifications pouvant proposer des complications étaient déjà véhiculées dans les versions 7.2 , 7.3 et 7.4 . Parlons maintenant des derniers changements. Ce sont :

L'héritage des citations magiques

  • Le vrai type
  • Filtre FILTER_SANITIZE_MAGIC_QUOTES
  • Dissocier $this des fermetures non statiques
  • array_key_exists() avec des objets
  • mb_strrpos() avec encoding comme 3ème argument
  • Méthodes export() de réflexion
  • fonction convert_cyr_string()
  • mélange d'ordre de paramètre implode()
  • fonction restore_include_path()
  • fonction hebrevc()
  • fonction money_format()
  • directive ini allow_url_include
  • Fonction ezmlm_hash()

Nouvelles fonctions en PHP 8

str_contains

Si une chaîne en contient une autre, il existe de nombreuses façons de le savoir.

Généralement, vous utiliserez strpos(). Comme vous le savez, strpos() prend une botte de foin à côté de l'aiguille que vous souhaitez rechercher. Il renvoie un entier indiquant la première position à laquelle vous voyez l'aiguille.

Maintenant, comme il renvoie la position d'une chaîne dans une autre, vous ne pouvez tout simplement pas vérifier si strpos() l'a découverte ou non ; s'il renvoie "0" (les positions sont indexées à zéro et commencent par 0 plutôt que par 1), alors la condition va la traiter comme une valeur fausse et indiquer qu'elle n'a pas été trouvée.

Qu'est-ce que cela signifie?

Vous devrez écrire le conditionnel -"strpos($haystack, $needle) !== false". False indique qu'il n'a pas pu trouver la position de la chaîne. Il s'agit d'une méthode non transparente et ésotérique pour rechercher une chaîne dans une chaîne ! Eh bien, pas si déroutant.

Pour éviter cela, PHP 8 apporte str_contains(). Le travail de str_contains() est de renvoyer un booléen simple indiquant si l'aiguille est présente ou non dans la botte de foin. C'est beaucoup plus facile à écrire, à part ça, à comprendre comme quelqu'un qui maintient le code, n'est-ce pas ?

 if (str_contains( 'Foo Bar Baz' , 'Foo' )) { // FOUND }

PHP 8 : Fonctionnalités et modifications du moteur

Il y a quelques nouvelles fonctionnalités de moteur et des changements remarqués dans PHP 8. La fonctionnalité principale est sans aucun doute le nouveau compilateur JIT.

Compilateur JIT

  • Application des LSP
  • Erreurs fatales sur des signatures de méthode incompatibles
  • Ressource "Cours"
  • XML-RPC est maintenant en PECL
  • Comportement d'assertion
  • Changements de réflexion

Dans l'intérêt de l'objectif principal de ce blog, nous nous concentrerons sur le compilateur JIT, les "classes" de ressources et enfin, les modifications de l'API de réflexion.

Compilateur juste-à-temps ( RFC )

En raison des améliorations de vitesse apportées avant la sortie de PHP7, la naissance du compilateur Just-In-Time (ou JIT) a eu lieu. Il est introduit dans PHP8 car il n'y a presque plus d'améliorations de la vitesse qui peuvent être apportées sans utiliser de JIT. L'idée est que cela améliorera les performances de PHP.

Le code PHP est traduit en bytecodes lorsqu'il est exécuté, et ces bytecodes sont ensuite utilisés pour exécuter les étapes du programme.

PHP analysera le code que vous avez exécuté, c'est ce que signifie un JIT. De plus, il peut prendre des décisions en temps réel autres que l'amélioration des performances du code lorsque vous l'exécutez. Il sera très utilisable dans les applications gourmandes en CPU et pas seulement lorsqu'il est utilisé dans des scénarios Web.

Cela reflète les applications PHP côté serveur qui peuvent certainement être plus répandues avec le système JIT intégré à PHP.

Vous devez d'abord activer JIT si vous souhaitez l'utiliser. Sur notre système de test (Ubuntu 20.04), nous avons déjà installé le module PHP opcache, que nous avons installé avec le package principal PHP8. Nous avons configuré dans le fichier placé dans /etc/php/8.0/cli/conf.d/10-opcache.ini.

Maintenant, vous êtes prêt à activer JIT, n'est-ce pas ?  

  • Activer l'opcache

Vous pouvez attribuer un stockage de mémoire au paramètre opcache.jit_buffer_size . Votre fichier apparaîtra comme ceci sur mon système.

  1. zend_extension=opcache.so
  2. opcache.enable_cli=1
  3. ; configuration du module php opcache
  4. opcache.jit_buffer_size=256M

De plus, utilisez la fonction opcache_get_status() pour vous assurer qu'elle est active. Passez votre regard sur la partie « jit » de ce tableau et obtenez des informations sur l'état actuel de JIT.


var_dump(opcache_get_status()['jit']);

Si JIT a été parfaitement activé, cela devrait s'imprimer comme indiqué ci-dessous.

  1. tableau(7) {
  2. [“activé”]=>
  3. bool (vrai)
  4. ["sur"]=>
  5. bool (vrai)
  6. [“gentil”]=>
  7. entier(5)
  8. [“opt_level”]=>
  9. entier(4)
  10. [“opt_flags”]=>
  11. entier(6)
  12. [“buffer_size”]=>
  13. entier(268435440)
  14. [“buffer_free”]=>
  15. entier(268432880)
  16. }

Alors c'était plus rapide ? En un mot, nous crierions un « oui » chaleureux.

Nous avons remarqué que quelques personnes faisaient des benchmarks à l'aide d'un ensemble de mandelbrot, nous avons donc décidé d'utiliser une bibliothèque que nous avons créée il y a quelque temps et qui dessine différentes sortes de fractales en PHP. Tout ce que nous avons fait a été de générer trois fractales et de suivre le temps qu'il a fallu en utilisant la fonction microtome(). Nous avons affiché les résultats pour PHP 7.4.8 ci-dessous.

  • Burningship – 84.20269203186
  • Mandlebrot – 21.552599906921
  • Tricorne – 32.685042858124

Lorsque nous avons exécuté le même code sur PHP8, c'était assez rapide. Les chiffres parleront d'eux-mêmes. .

  • Burningship – 15.272277116776
  • Mandlebrot-3.7528541088104
  • Tricorne -4.4957919120789

Cette énorme augmentation de vitesse est assez intéressante. Le code que nous avons utilisé ici crée des fractales de grande taille, mais nous nous souvenons lors de la création du code que la plupart de notre temps a été passé à attendre la génération de fractales.

Cet ajout nous intéresse car nous avons poussé PHP à ses limites à certaines occasions (en dehors de la génération de fractales). Nous pouvons remarquer que cela est très bénéfique pour l'avenir de PHP et va permettre de choisir la langue pour des situations en dehors de la langue habituelle du site Web.

Nous n'avons pas examiné l'incrément de vitesse pour des applications comme WordPress ou Drupal, mais d'après ce que nous avons lu, il y a certainement peu de différence dans ce type d'applications. À l'avenir, nous effectuerons des tests de performance sur ces plates-formes pour déterminer le type de différence que le JIT y marque.

Types d'union ( RFC )

Depuis PHP7, stipulant quel type de valeurs de retour et types d'arguments et ont été possibles. Cela permettra à PHP de générer une erreur dans le cas où le type d'argument que vous passez est un tri non identique au type attendu. Il est crucial de s'assurer que les fonctions reçoivent et produisent les types de valeur parfaits dans un langage faiblement typé tel que PHP.

En PHP8, il est désormais possible de stipuler différentes sortes pour les arguments et les valeurs de retour, séparées par un caractère pipe.

Nous avons montré ci-dessous une fonction capable d'accepter une valeur flottante ou une valeur entière.

 function addNumbers(int|float $number1, int|float $number2) : int|float { return $number1 + $number2; }

Auparavant, une fonction identique à celle-ci nécessitait d'être générée sans aucune indication de type car PHP pouvait afficher silencieusement le type au cas où l'argument passé n'était pas correct. Cela signifiait que si nous définissions le type d'argument comme un entier, PHP présenterait toutes les valeurs flottantes dans un entier. Cela peut certainement conduire à quelques bugs délicats à détecter au cas où vous ne testez pas unitaire.

Nous l'appelons simplement comme n'importe quel autre pour utiliser la fonction ci-dessus

 echo addNumbers(1, 1); // prints 2 echo addNumbers(1.1, 1.1); // prints 2.2

Dans le cas où nous essayons de passer une chaîne à la fonction identique :

 echo addNumbers('one', 'two');

Nous recevrons une erreur PHP Fatal s'exclamant que nous devons passer soit un float soit un "int" dans la fonction.

Vous ne pouvez pas utiliser le type void comme type union car il stipule que la fonction ne renverra rien. En termes simples, vous ne pouvez pas vous exclamer qu'une fonction va renvoyer un vide ou un entier ; vous recevrez une erreur fatale PHP.

Alors qu'un changement normal que nous pouvons voir était que cette fonctionnalité était un peu utilisée car il n'était auparavant possible que de stipuler différents types de valeur dans les commentaires, ce qui a fait que les commentaires de bloc doc devenaient plus détaillés que le code.

L'opérateur Nullsafe (RFC)

Outre l'opérateur de coalescence nul, la capacité de détecter les valeurs de retour nulles est possible directement à partir des méthodes. Si vous ne le saviez pas, l'opérateur de coalescence nul vous permet d'obtenir une valeur, et vous n'avez pas à tester si la valeur est présente en plus de renvoyer une valeur différente si la première valeur est nulle.

Donc, nous pouvons le faire pour extraire une valeur de - "$ _GET superglobal". et si cette valeur n'est pas présente, alors "0".


1. $page = $_GET['page'] ?? 0;

2. echo $page;

Le fonctionnement de l'opérateur null safe est le même mais vous permet de créer un raccourci pratique et de tester un retour null d'une manière avant d'essayer d'utiliser cette valeur.

Nous avons remarqué que cela va être finalement utile dans Drupal, où nous avons tendance à écrire une grande partie du code de vérification pour nous assurer que les « retours des méthodes » ou les « propriétés d'objet » contiennent des éléments avant de les utiliser. Ceci est obligatoire en raison de l'état contextuel des objets dans Drupal en raison du contenu qu'ils contiennent. Ce changement simplifiera sûrement certaines vérifications.

Arguments nommés ( RFC )

Les arguments nommés vous permettent de spécifier un ordre différent d'arguments et d'appeler des fonctions. Prenez la fonction normale suivante qui a deux paramètres. Il remplit un tableau à la longueur donnée.

 function fillArray(array $arrayToFill, int $number) : array { for ($i = 0 $i < $number; ++$i) { $arrayToFill[$i] =1; } return $arrayToFill; }

Nous pouvons passer les arguments dans l'arrangement où ils sont définis et appeler cette technique de la manière habituelle.

 $newArray = fillArray([], 2);

Depuis PHP8, vous pouvez nommer les paramètres au fur et à mesure que vous les transmettez à la fonction. Il vous permet également d'envoyer les paramètres dans l'ordre que nous voulons.

 $newArray = fillArray(number: 2, arrayToFill: []);

Un exemple normal, mais il peut également rendre le code plus lisible.

Cette technique fonctionne avec toutes les fonctions de PHP, pas seulement celles définies par l'utilisateur. En langage PHP, les fonctions de tableau et de chaîne ont des ordres de paramètres non identiques. C'est donc un ajout vraiment bienvenu.

Attributs V2 ( RFC1 RFC2 RFC3 )

Les attributs fournissent un mécanisme pour joindre les métadonnées aux classes, fonctions, propriétés de classe, paramètres de fonction et constantes PHP. Ils ne peuvent pas être directement accessibles via le code, et vous devez les extraire à l'aide de PHP construit dans des classes de réflexion.

La classe ReflectionClass est en PHP depuis PHP5 ; cependant, la méthode getAttribute() est nouvelle pour PHP8. Cette méthode renvoie une plage d'objets ReflectionAttribute qui vont contenir des informations sur les attributs.

Cet ajout a subi quelques changements (comme nous pouvons le remarquer dans les multiples RFC ci-dessus). Si vous instanciez la classe, vous pouvez ensuite utiliser ReflectionClass et imprimer les informations d'attribut contenues au niveau de la classe. Il y a beaucoup d'attributs dans PHP8, nous vous recommandons donc de lire les RFC et de vous familiariser avec ce qu'ils sont réellement et comment vous pouvez les intégrer dans votre code.

Expression de correspondance ( RFC )

En PHP 8, nous pouvons comparer la nouvelle expression de correspondance à une instruction switch abrégée.

Cela ressemble un peu à une déclaration de fonction qui va renvoyer une valeur sur la base de la valeur transmise.

L'instruction switch en PHP est incroyable lorsque vous souhaitez vérifier la condition sur l'expression identique sans inclure plusieurs instructions if .

Ici, nous apportons une comparaison de base if-else sur une expression identique.

 <?php if ($i == 'apple') { echo 'i is apple'; } elseif ($i == 'cake') { echo 'i is cake'; } else { echo 'i is pizza'; }

Et voici comment l'instruction switch équivalente de notre exemple précédent apparaîtrait comme

 <?php switch ($i) { case 'apple': echo 'i is apple'; break; case 'cake': echo 'i is cake'; break; default: echo 'i is pizza'; }

Ressource "Cours"

Les "classes" de ressources figurent dans la liste des modifications majeures de PHP 8 et servent de remplacements non instanciables pour des types de ressources donnés. Voir ci-dessous pour connaître les remplacements disponibles :

  • CurlHandle - curl_init () renvoie maintenant CurlHandle, reliant une ressource curl.
  • Socket / AddressInfo — Donné par l'extension sockets ; la quantité des fonctions socket_*() renvoie un Socket, tandis que la fonction socket_address_info_lookup() renvoie une instance AddressInfo.
  • GdImage — Il représente une ressource GD, telle que restaurée par les nombreuses fonctions imagecreatefrom*().

De plus, il est crucial de noter que les ressources ne sont pas détruites par des fonctions telles que curl_close(). Au lieu de cela, vous devez unset() l'instance pour la déréférencer car il s'agit maintenant d'une instance de classe.
Vous avez la possibilité de spécifier les classes en tant qu'indications de type dans vos fonctions et méthodes.
Auparavant, nous devions renvoyer des valeurs non typées ou laisser des arguments de ressource et les documenter via des annotations, mais maintenant, vous pouvez avoir des types explicites, ce qui rend non seulement votre code plus lisible, mais également plus sûr.
Quel est le compromis ici?
Vous devrez maintenant mettre à jour votre code si vous souhaitez détruire des ressources à l'aide de unset() à la place des fonctions précédentes utilisées pour démolir des ressources. Cela peut normalement être accompli par la recherche et le remplacement.

Modifications de l'API de réflexion

Un autre petit, mais un changement vital dans PHP 8 est lié à l'API Reflection. Lorsque vous utilisez le système d'attributs, vous pouvez facilement récupérer ces attributs via l'API Reflection sur n'importe quelle classe de réflexion.
Avec l'ajout des types mixtes et union, les techniques ReflectionParameter getClass(), isCallable() et isArray() sont désormais obsolètes.
Le scénario est ainsi parce que l'utilisation de getType(), est bien meilleure, et vous obtenez la liste complète des types qu'un paramètre spécifique satisfait.

Améliorations de la syntaxe PHP 8

Comme nous le remarquons, JIT fait la une des journaux ; les améliorations syntaxiques de PHP 8 offrent d'énormes avantages de qualité de vie aux développeurs PHP.
Qu'il s'agisse d'éliminer le passe-partout commun parmi les arguments de constructeur promus ou d'améliorer la gestion des exceptions et des erreurs, les développeurs ont de quoi se sentir enthousiasmés.

  • pseudo-type "mixte"
  • Types de syndicats
  • Promotion de la propriété Class Constructor
  • Lever des exceptions à partir d'expressions
  • Les attributs
  • :: ubiquité des classes
  • Capture par type uniquement
  • Correspondance des expressions

Pour la maintenance de ce blog, nous nous concentrons sur les types d'union, les attributs et les expressions de correspondance.

Types de syndicats

Les types d'union montrent qu'une valeur est l'une parmi deux ou plusieurs sortes spécifiées. C'est fait avec une barre verticale placée entre chaque type autorisé. Pour plusieurs développeurs qui sont profondément ancrés dans les annotations PHP pour renvoyer des valeurs ou spécifier vos paramètres, vous l'avez probablement déjà fait.
Les types d'union peuvent apporter beaucoup de complexité et de difficulté à comprendre pour ceux qui acceptent beaucoup de types différents ou renvoient beaucoup de types différents.
Néanmoins, cela vous sera très utile à plusieurs reprises. Par exemple, si vous pouvez accepter soit un objet implémentant la nouvelle interface Stringable ("string|Stringable"), soit une chaîne, ou si vous pouvez accepter soit un objet implémentant l'interface Traversable ("array|Traversable") soit un tableau .

Correspondance des expressions

Les expressions de correspondance éliminent les conjectures liées à la détermination de l'échec de la rupture dans un cas de commutation donné est intentionnel ou non. Cela simplifie également le modèle normal d'attribution d'une valeur sur la base d'une correspondance.
Lorsqu'elle est utilisée, la valeur que nous transmettons à match() sera directement comparée à l'expression qui se trouve sur le côté gauche. Qu'il s'agisse d'une expression ou d'une valeur, la valeur que vous transmettez à match() doit correspondre pour qu'elle soit choisie.
En cas de correspondance, l'expression présente à droite est estimée et sa valeur de retour est renvoyée, tandis que les expressions ne peuvent être que des fonctions Lambda ou appelables, et aucune fermeture multiligne n'est autorisée.

Les attributs

PHP 8 intègre également des attributs au niveau du langage. Alors que les attributs sont présents depuis plus de 15 ans via les annotations docblock, les intégrer au langage offre de meilleures performances et certainement, plus de puissance et plus de cohérence. Nous verrons probablement des attributs très utilisés dans le développement d'outils et d'applications rapides.

Conclusion

Certes, il y a quelques changements dans PHP8. Pourtant, il semble que la majorité du code obsolète éliminé concerne des fonctionnalités plus anciennes que nous n'avons pas vues utilisées ces derniers temps.
Nous sommes très intéressés de constater l'impact que le moteur JIT aura sur les bases de code que nous utilisons et également sur la communauté PHP au sens large. Nous vous recommandons vivement d'analyser votre base de code à la recherche d'incompatibilités avec PHP8 et d'exécuter des tests unitaires pour vous assurer que votre PHP les applications fonctionnent parfaitement avant de dire "oui" à la mise à jour.