PHP 7.4 est sorti! Comment les mises à niveau de Badoo

Aujourd'hui, enfin, la version de PHP 7.4 est publiée!


Ses nouvelles fonctionnalités ont déjà été décrites à plusieurs reprises, notamment sur Habré . Ce sont des fonctions fléchées, des propriétés typées de classes et beaucoup plus de sucre syntaxique. Mais surtout, nous attendions une nouvelle version en raison des performances : dans la version 7.4, non seulement la précharge est apparue, mais PHP lui-même est devenu beaucoup plus rapide.

Mauvaise (ou bonne?) Nouvelles - avec la sortie de PHP 7.4, le support actif de PHP 7.2 cesse . Sa dernière sortie est prévue pour la mi-décembre. Nous expérimentons PHP 7.4 depuis longtemps, et récemment nous sommes activement engagés dans la transition vers celui-ci, puisque nous sommes maintenant sur la version 7.2 presque non prise en charge.

Félicitations à tous pour la sortie tant attendue! Et ci-dessous, je vais parler un peu de la façon dont nous mettons à niveau la nouvelle version.

Malgré le fait que nous ayons une énorme base de code, nous vivons en PHP depuis 13 ans. Nous avons dû à plusieurs reprises mettre à niveau vers de nouvelles versions, et le processus de transition est bien établi.

S'il est grandement simplifié, on peut distinguer plusieurs étapes:

  • Nous nous assurons que les tests unitaires commencent à réussir avec succès sur la nouvelle version.
  • Nous rendons les tests sur la nouvelle version obligatoires pour toutes les modifications de code (afin que vous n'ayez pas à répéter l'étape 1, car le nouveau code est écrit en permanence et il peut de nouveau être incompatible).
  • Nous passons à la nouvelle version de la plate-forme de développement, résolvons les problèmes et vivons un certain temps dans cet état.
  • Répétez cette opération pour la mise en scène.
  • Nous l'étalons en douceur sur différents clusters de production.

Nos modifications dans le référentiel PHP


Problème de précharge ( correction )


Cette fois, quelque chose a changé dans le processus: depuis que nous attendions la précharge, nous avons commencé à effectuer une partie du travail en juillet, lors de la version 7.4.0beta1. En conséquence, cela a entraîné un temps assez important pour le débogage pour nous, car PHP 7.4 était alors complètement brut. Mais d'un autre côté, en conséquence, nous avons trouvé un bug désagréable, l'avons corrigé et envoyé le correctif à l'amont, ce qui a aidé toute la communauté.

Ensuite, il est temps de faire les tests.

Problème d'accès aux propriétés privées ( correction )


Pour exécuter des tests en général, vous devez mettre à jour PHPUnit, SoftMocks et PHP-Parser dans le cadre de ceux-ci. Nous avons une grande base de code, et même pour mettre à jour PHPUnit, il était nécessaire de réécrire un grand nombre de tests.

Après avoir réussi à exécuter les tests, nous avons vu une chose très étrange. Il y a eu de nombreux plantages avec l'erreur suivante:

PHP Fatal error: Cannot access private property ClassLoader::$classMap in vendor/composer/ClassLoader.php 

L'accès à la propriété privée d'une classe s'effectue uniquement à l'intérieur de celle-ci, mais PHP signale une erreur: vous ne pouvez pas accéder à la propriété privée comme si l'appel venait d'une autre classe.

Le problème était compliqué par le fait qu'il était reproduit de manière instable. Un long débogage utilisant gdb a montré que, pour une raison quelconque, EG (fake_scope) n'a pas la classe dans laquelle la propriété est accédée, mais une autre qui ne lui est pas liée.

Après avoir trouvé un cas de reproduction minimal (qui, pour un moment, nécessite trois classes, un chargeur automatique et une réflexion), corrigé la cause du problème et commencé à le résoudre en amont, il s'est avéré que ce problème existait depuis PHP 7.3 (très probablement, après ce changement), le monde entier a vécu avec elle pendant un an et elle n'a dérangé personne avant nous.

Règle d'incompatibilité du code Badoo


Nous corrigeons maintenant toutes les incompatibilités de notre code avec PHP 7.4. La grande majorité des incompatibilités pour nous (plus d'une centaine de places,> 80% de toutes les incompatibilités) ont été causées par l'ajout de l'erreur "Essayer d'accéder au décalage du tableau sur une valeur de type null / bool / int" ( correspondant à RFC ). Cela se produit lors de l'utilisation de la syntaxe d'accès à un élément de tableau sur d'autres types de données.

L'exemple suivant illustre bien le problème:

 $a = false; var_dump($a['somekey']); // PHP 7.3: // NULL // // PHP 7.4: // Notice: Trying to access array offset on value of type bool in Command line code on line 1 // NULL 

Offhand, il semble que cela ne devrait pas se produire dans le code réel, mais, comme la pratique l'a montré, c'est un cas assez courant: par exemple, une fonction peut renvoyer un tableau dans le cas normal et false / null en cas d'erreur, et remonter les informations de la pile sur false / null est perdu et ce cas n'est pas traité séparément.

C'est un changement assez peu propagé, mais utile en PHP: il vous permet de trouver de nombreuses erreurs potentielles dans le code.

La deuxième mise à jour en termes de problèmes évoqués est un changement dans le fonctionnement de method_exists (). Soit dit en passant, pour le moment, il n'y a aucune information à ce sujet dans les notes de version ou le guide de mise à niveau. Son essence est la suivante:

 class A1 {    private function priv() {} } class B1 extends A1 {} var_dump(method_exists(B1::class, 'priv')); // PHP 7.3: bool(true) // PHP 7.4: bool(false) 

Cette fonctionnalité, encore une fois, est difficile à trouver dans le vrai code. Mais, il s'est avéré que nous avons involontairement activement exploité cela dans les tests.

Bien sûr, nous sommes confrontés à différents degrés à d'autres incompatibilités, y compris de nombreux changements liés à la réflexion ( exemple un , exemple deux ), des changements à hexdec () et similaires, l' interdiction de array_key_exists () même pour les objets ArrayAccess, avec incompatibilités dans diverses bibliothèques de dépendances connectées via Composer, et même avec toutes sortes de choses exotiques, telles que stream_set_option () qui est devenu obligatoire pour les wrappers de flux pour include. Mais au total, les coûts d'adaptation à tous ces changements ne peuvent être comparés au cas de l'utilisation de la syntaxe des tableaux sur des non-tableaux.

Pour le moment, nous avons fini de travailler avec les tests unitaires: ils passent entièrement en PHP 7.4. Nous travaillons sur des tests d'API et prévoyons de commencer à changer de clusters et d'environnements d'ici la fin de l'année.

Je veux vous inviter à cette discussion pour discussion: avez-vous déjà essayé PHP 7.4? Si oui, quelle a été votre expérience? Allez-vous traverser?

Source: https://habr.com/ru/post/fr477822/


All Articles