PHP 7.3. Quoi de neuf


Syntaxe


  1. Adoucir les exigences de syntaxe Heredoc et Nowdoc
  2. Prise en charge des virgules de fin dans les appels de fonction et de méthode
  3. Liens dans la list()

Fonctionnalités obsolètes (obsolète)


  1. image2wbmp() déconseillée
  2. Les FILTER_FLAG_SCHEME_REQUIRED et FILTER_FLAG_HOST_REQUIRED lors de l'utilisation de FILTER_VALIDATE_URL
  3. Enregistrer les constantes indépendantes obsolètes

De nouvelles fonctionnalités


  1. json_encode exception facultative pour les erreurs dans les fonctions json_encode et json_decode
  2. Ajout de la fonction is_countable()
  3. Ajout des fonctions array_key_first() et array_key_last()

Changements


  1. Migration de PCRE vers PCRE2

Adoucir les exigences de syntaxe Heredoc et Nowdoc


Heredoc et Nowdoc ont demandé de mettre l'identifiant de fermeture en premier dans une nouvelle ligne.


Un exemple:


 $foo = <<<IDENTIFIER the crazy dog jumps over the lazy fox "foo" bar; IDENTIFIER 

Ici, l' IDENTIFIER fermeture doit être le premier caractère de la nouvelle ligne pour que cela fonctionne. De plus, il ne devrait pas y avoir d'autres caractères après l'identifiant de fermeture (sauf ; qui est facultatif).


Le RFC pour PHP 7.3 suggère de supprimer ces exigences pour améliorer la lisibilité du code. Tout d'abord, pour ajouter une indentation lors de l'utilisation des identifiants heredoc/nowdoc .


Liste complète des modifications apportées à la syntaxe heredoc/nowdoc :


  1. L'identifiant de fermeture ne doit pas nécessairement être le premier caractère de la chaîne.
  2. L'identifiant de fermeture est en retrait avec des espaces ou des tabulations.
  3. Le retrait (espaces ou tabulations) ne doit pas être mélangé. Si vous faites cela, vous obtiendrez une Parse error: Invalid indentation - tabs and spaces cannot be mixed in .. on line ..
  4. Le nombre exact d'espaces / tabulations utilisés avant l'identifiant de fermeture sera supprimé de chaque ligne de l'expression heredoc/nowdoc .
  5. Si le nombre de caractères de retrait utilisés avant l'identificateur de fermeture est supérieur à celui de l'une des lignes de l'expression, vous obtiendrez une Parse error: Invalid body indentation level (expecting an indentation level of at least ..) in .. on line ..
  6. plusieurs expressions après l'identifiant de fermeture fonctionneront sans erreur

Voici un extrait qui tire parti des nouvelles fonctionnalités sans enfreindre de nouvelles règles:


 $foo = ['foo', 'bar', <<<EOT baz - hello world! -- ahoy EOT, 'qux', 'quux' ]; var_dump($foo); 

La sortie sera:


 array(5) {        [0]=>           string(3) "foo" [1]=>           string(3) "bar" [2]=>           string(29) "baz - hello world! -- ahoy" [3]=> string(3) "qux" [4]=> string(4) "quux" }     ` 

Notez que l'indentation utilisée dans la déclaration utilisant heredoc pas affichée dans la sortie de var_dump() , et nous avons continué à lister les éléments du tableau après l'identifiant EOT .


RFC , discussion sur Externals.io , implémentation


Impact de la compatibilité descendante


Jusqu'à ce que vous heredox/nowdoc un ensemble d'identifiants de caractères heredox/nowdoc identiques au début d'une ligne, vous êtes à cheval.


 $foo = <<<HELLO HELLO_WORLD <--         HELLOWORLD <--     HELLO WORLD <--    HELLO; 

Si vous avez heredoc/nowdoc syntaxe heredoc/nowdoc similaire à celle décrite ci-dessus, je note qu'avec PHP 7.3, PHP acceptera le premier littéral HELLO et lancera une erreur sur la ligne suivante. Dans les versions antérieures, HELLO WORLD pas perçu comme un identifiant de fermeture pour heredoc. Merci / u / ImSuperObjective2 avec reddit pour l' avoir signalé


Prise en charge des virgules de fin dans les appels de fonction et de méthode


Il s'agit d'un simple changement qui permet d'utiliser des virgules de fin dans les appels de fonction et les méthodes. Cela n'affecte pas la déclaration.


Par exemple, la syntaxe suivante deviendra possible:


 //  foo('bar', 'baz',); //        'baz' 

Dans les versions antérieures à PHP-7.3, l'extrait ci-dessus renvoie une PHP Parse error: syntax error, unexpected ')' in .. on line ..


Vous ne pouvez pas utiliser plus d'une virgule à la fin ou utiliser des virgules pour ignorer les arguments. Il s'agit principalement d'un changement pour une fonction à paramètres variables. De plus, avec les nouvelles modifications, la syntaxe du tableau sera plus cohérente.


Notez que vous ne pouvez pas utiliser cette fonctionnalité dans les déclarations de fonction / méthode; c'est faux:


 function foo($bar, $baz, ) { // nah, you can't do this. } 

RFC , discussion sur Externals.io , implémentation


Impact de la compatibilité descendante


Rien. Le code existant continuera de fonctionner. Si vous avez des appels de fonction qui acceptent des paramètres variables, ajoutez des virgules de fin à ces emplacements pour plus de commodité. Mais les utiliser partout, c'est évidemment trop.


Liens dans la list()


La fonction list() est utile pour attribuer rapidement des valeurs aux variables d'un tableau. Avant PHP 7.3, il n'était pas possible de spécifier une variable par référence. Avant PHP 7.3, l'extrait de code suivant entraînait une erreur fatale:


 $arr = ['apple', 'orange']; list($a, &$b) = $arr; $b = 'banana'; echo $arr[1]; // Fatal error: [] and list() assignments cannot be by reference in .. on line .. 

Il est impossible de se référer à non-referencable variables non-referencable : list($a, &$b) = [12, 14]; donnera une Fatal error: Cannot assign reference to non referencable value in .. on line ..


RFC , discussion sur Externals.io , implémentation


Impact de la compatibilité descendante


Non. Au lieu d'utiliser list() pour remplir plusieurs variables, je vous suggère d'utiliser des objets de valeur pour simplifier les choses. Ils seront toujours transmis par référence, mais rendront votre code beaucoup plus propre.


image2wbmp() déconseillée


image2wbmp() fonction image2wbmp() de l'extension GD est utilisée pour produire des images au format WBMP (Wireless Bitmap). En PHP 7.3, il est déconseillé au profit de la fonction imagewbmp() .


Si vous utilisez image2wbmp() , remplacez simplement le nom de la fonction par imagewbmp et tout ira bien! Plus de 5,500 image2wbmp() sur github contre plus de 39,300 imagewbmp() . Il semble que l'équipe de développement PHP supprime les fonctionnalités moins utilisées pour minimiser l'impact.


RFC , discussion sur Externals.io , implémentation


Impact de la compatibilité descendante


Si vous utilisez la fonction image2wbmp() , remplacez l'appel par imagewbmp . Profitez de l'automatisation qui peut changer cela pour vous.


Les FILTER_FLAG_SCHEME_REQUIRED et FILTER_FLAG_HOST_REQUIRED lors de l'utilisation de FILTER_VALIDATE_URL


Il s'agit d'un mouvement vers l'avant. Lorsque vous utilisez filter_var($var, FILTER_VALIDATE_URL) , deux indicateurs supplémentaires peuvent être définis pour garantir une vérification stricte des URL: FILTER_FLAG_SCHEME_REQUIRED et FILTER_FLAG_HOST_REQUIRED .
Depuis PHP 5.2.1, ces deux indicateurs sont appliqués implicitement, qu'ils soient définis ou non.


Si votre code utilise ces indicateurs, supprimez-les simplement et tout ira bien. Plus de 5 000 résultats de recherche github les utilisent actuellement.


RFC , discussion sur Externals.io , implémentation


Impact de la compatibilité descendante


Étant donné que ces deux indicateurs sont obsolètes, vous verrez une notification comme:


 Deprecated: filter_var(): explicit use of FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED is deprecated in ... 

Tout ce que vous avez à faire est de retirer les deux drapeaux, comme ils sont FILTER_VALIDATE_URL impliqués lors de l'utilisation de FILTER_VALIDATE_URL .


Enregistrer les constantes indépendantes obsolètes


La fonction define() vous permet de déclarer une constante en mode insensible à la casse. Vous devez déclarer explicitement une constante sensible à la casse en passant le troisième paramètre de la fonction true . Ce n'est pas le comportement par défaut et n'est probablement pas compatible avec la possibilité de déclarer des constantes via le mot clé const .


 define('Foo', 'Bar', true); 

Le code ci-dessus lancera une notification d'obsolescence: Deprecated: define(): Declaration of case-insensitive constants is deprecated in ...


En outre, lorsque vous essayez d'accéder à des constantes qui ont été déclarées en mode FOO ( Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "Foo" ), vous verrez un avertissement assez utile: Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "Foo" Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "Foo"


RFC , discussion sur Externals.io , implémentation


Impact de la compatibilité descendante


Vous devrez vous rendre au code de base, où les constantes indépendantes du registre sont déclarées puis correctes. Il est extrêmement improbable qu'il y ait des problèmes avec cela, car il est plutôt laborieux d'attraper tous les cas d'utilisation, mais en conséquence, le code deviendra plus clair.


Je n'ai trouvé aucun exemple de cette utilisation sur github, mais au moins Drupal et WordPress (deux projets PHP assez anciens et matures) ont des constantes insensibles à la casse.


json_encode exception facultative pour les erreurs dans les fonctions json_encode et json_decode


Un de mes préférés. Pendant toutes ces années, json_encode() et json_decode() gardé le silence sur les erreurs dans les variables PHP ou les chaînes json, ce qui a conduit au code qui a été balisé. Ce cas était même dans la célèbre critique de PHP: une fractale de mauvaise conception .


json_decode renvoie null pour une entrée non valide, tandis que null est un objet absolument vrai pour le JSON décodé. Cette fonction n'est absolument pas fiable, à moins bien sûr d'appeler json_last_error chaque fois que vous l'utilisez.

Cela a pris 6 ans après ce billet de blog et nous avons eu l'occasion d'obtenir une erreur sur les échecs json:


 try { json_decode("{", false, 512, JSON_THROW_ON_ERROR); } catch (\JsonException $exception) { echo $exception->getMessage(); //  "Syntax error" } 

La nouvelle \JsonException est un descendant de \Exception , ainsi que la constante JsonException et JsonException elle-même sont dans l'espace de noms global.


Je vous recommande fortement de commencer à utiliser cette fonctionnalité. Il existe des bibliothèques tierces, telles que daverandom / exceptionnel-json , qui implémentent des fonctionnalités similaires pour les versions PHP 7.2 et inférieures. Avec l'apparition de cette fonction dans le noyau PHP, vous pouvez supprimer ce paquet et des tonnes de code de modèle laid avec l'appel json_last_error() à chaque endroit où vous travaillez avec json.


RFC , discussion sur Externals.io , implémentation


Impact de la compatibilité descendante


Rien si vous n'utilisez pas votre propre exception et / ou constante avec les mêmes noms.


Ajout de la fonction is_countable()


PHP 7.2 a beaucoup de fonctions obsolètes et boguées. Si vous êtes en PHP 7.2. appelez count() utilisant une variable non countable , puis PHP affichera un avertissement à ce sujet. Dans les modifications générales, il a été proposé de vérifier la variable résultante pour countable avant de l'utiliser dans count() .


countable -variable est un tableau ou un objet qui implémente l'interface \Countable . Étant donné que beaucoup de code passe-partout sera utilisé lors de la vérification, PHP 7.3 a introduit une nouvelle fonction is_countable() , qui vérifie la variable pour ... eh bien ... la possibilité d'utiliser count() .


J'ai écrit un polyfichier pour is__countable () si vous voulez commencer à utiliser cette fonctionnalité maintenant.


RFC , discussion sur Externals.io , implémentation


Impact de la compatibilité descendante


Jusqu'à ce que sa propre fonction is_countable() soit is_countable() , il n'y aura aucun problème.


Ajout des fonctions array_key_first() et array_key_last()


Il existe 75 fonctions différentes en PHP pour travailler avec des tableaux, mais jusqu'à présent, il n'y a pas eu de moyen facile d'obtenir les première et dernière clés d'un tableau sans changer le pointeur du tableau ou énumérer toutes les clés (via array_keys() ), puis obtenir la première / dernière valeur.


Deux nouvelles fonctions sont array_key_first() , array_key_first() et array_key_last() vous permettant de le faire.


Le RFC a également suggéré d'ajouter array_value_first() et array_value_last() , mais cette partie n'a pas passé le vote.


RFC , discussion sur Externals.io , implémentation


Impact de la compatibilité descendante


Si vous n'avez pas déclaré vos propres fonctions array_key_first() et array_key_last() , aucun problème.


Migration de PCRE vers PCRE2


PHP utilise des expressions régulières compatibles Perl ou brièvement PCRE dans la bibliothèque pour travailler avec des expressions régulières. Depuis PHP 7.2, la version 8.x de la bibliothèque héritée PCRE a été utilisée et en PHP 7.3 PCRE2 sera déjà utilisée. Veuillez noter que PCRE2 est considéré comme une nouvelle bibliothèque, bien qu'il soit largement compatible avec PCRE (8.x).


La nouvelle bibliothèque est plus agressive dans la validation des modèles et peut entraîner des erreurs dans le code existant. L'extrait de code suivant ne sera pas valide avec PHP 7.3:


 preg_match('/[\w-.]+/', ''); 

PHP lancera un avertissement Warning: preg_match(): Compilation failed: invalid range in character class at offset 3 .
Le problème avec le motif: pour que cela fonctionne, le trait d'union doit être déplacé à la fin ou échappé.


 preg_match('/[\w\-.]+/', ''); 

Le code ci-dessus fonctionnera très bien non seulement avec PHP 7.3, mais aussi avec les anciennes versions. Dans le nouveau modèle, le tiret est échappé - vers \- . Il s'agit du problème le plus courant que vous pouvez rencontrer lors de la résolution de problèmes de compatibilité.


Il s'agit d'un changement assez mineur, mais il y a une chance que tout se passe mal. Le message d'erreur indique la position exacte du caractère dans l'expression régulière. Assurez-vous de vérifier attentivement votre code. Vérifiez la compatibilité de vos expressions régulières avec la syntaxe PCRE2 via Regex Buddy ou un autre logiciel similaire. Voir la description de la syntaxe PCRE2 et de la syntaxe PCRE héritée pour plus d'informations.


RFC , discussion sur Externals.io , implémentation


Impact de la compatibilité descendante


Étant donné que PCRE2 est plus pointilleux et strict sur les modèles, certains de vos preg_match() et similaires peuvent ne pas fonctionner. Le correctif varie de la simple mise à jour du modèle (par exemple, des tirets d'échappement) à la réécriture des modèles. Assurez-vous que tous vos tests réussissent.

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


All Articles