Le groupe PHP a publié la version 8.5 du langage de script open source qui alimente une grande partie du Web, y compris les sites utilisant le CMS WordPress.

La sortie de PHP 8.5 en novembre a marqué la deuxième année de l’engagement de la communauté PHP à fournir des mises à jour majeures selon un calendrier annuel, suivi de deux années complètes de support actif pour chaque version.

Bien que la version 8.5 soit toute nouvelle, nous l’avons déjà couverte dans notre analyse comparative annuelle de PHP derrière une variété de plates-formes CMS et de frameworks populaires.

Si vous envisagez de migrer des applications PHP vers la version 8.5, vous devez savoir ce qui a changé dans cette dernière version. Cela inclut les nouvelles fonctionnalités que vous pourriez exploiter pour améliorer votre code et les anciennes fonctionnalités que les développeurs de PHP s’apprêtent à supprimer.

Voici ce que nous pensons être les points forts de cette nouvelle version :

Nouvelles fonctionnalités et améliorations de PHP 8.5

Commençons par les nouveaux ajouts à la base de code PHP. Ces changements commencent généralement par des demandes de commentaires (Request for Comments ou RFC) qui peuvent être approuvées et assignées à une future version de PHP.

Les nouvelles fonctionnalités décrites ci-dessous sont celles qui retiennent le plus l’attention autour de PHP 8.5.

Chaîner des appels de fonction avec l’opérateur pipe

Un nouvel opérateur pipe (|>) enchaîne les appels de fonction d’une manière qui semblera vaguement familière aux programmeurs JavaScript. L’opérateur pipe fonctionne de gauche à droite, en passant une seule valeur le long de la chaîne à chaque étape.

Avec les versions précédentes de PHP, les programmeurs pouvaient accomplir une tâche similaire en imbriquant des fonctions ou en passant par une série d’appels de fonctions sur la valeur retournée à chaque étape.

Voici un exemple simple utilisant le nouvel opérateur pipe :

$text = ' New-in-php-8.4 ';

$result = $text
    |> trim(...)
    |> (fn($str) => str_replace('4', '5', $str))
    |> (fn($str) => str_replace('-', ' ', $str))
    |> strtoupper(...);

var_dump($result);
// string(14) "NEW IN PHP 8.5"

(Notez que nous utilisons la syntaxe d’appel de première classe (...) introduite en PHP 8.1 avec les appels de fonction trim() et strtoupper())

La chaîne pipée ci-dessus pourrait être écrite sur une seule ligne, mais la lisibilité est censée être l’un des avantages de ce nouvel opérateur.

Ce qui précède est équivalent à l’imbrication de ces opérations (dans l’ordre inverse) comme ceci :

$text = " New-in-php-8.4 ";

$result = strtoupper(
    str_replace(‘-, ' ',
        str_replace('4', '5', 
            trim($text)
         )
     )
);

Alternativement, un programmeur aurait pu réaliser cette tâche dans les versions antérieures de PHP comme ceci :

$text = " New-in-php-8.4 ";

$result = trim($text);
$result = str_replace('4', '5', $result);
$result = str_replace(‘-, ' ', $result);
$result = strtoupper($result);

Analyser les URL avec la nouvelle extension URI

Les URL (également connues sous le nom d’URI pour les plus exigeants) sont essentielles à la navigation sur le web, mais la fonction parse_url() intégrée à PHP depuis la version 4 est bien connue pour ses problèmes avec les entrées malformées qui peuvent conduire à des erreurs lors de la manipulation ou de la validation d’adresses de sites web.

Pour améliorer l’analyse des URL, PHP 8.5 incorpore les bibliothèques uriparser et Lexbor, qui supportent respectivement les standards RFC 3986 et WHATWG.

Vous pouvez invoquer la bibliothèque uniparser en commençant le travail avec la nouvelle extension URI comme ceci :

$uri = new UriRfc3986Uri("https://kinsta.com/blog/php-8-5/"); 

echo $uri->getScheme();       // https
echo $uri->getHost();         // kinsta.com
echo $uri->getPath();         // /blog/php-8-5

Vous pouvez également choisir la bibliothèque d’URL du WHATWG Lexbor en procédant comme ceci :

$uri = new UriWagWgUrl("https://kinsta.com/blog/php-8-5/"); 

echo $uri->getScheme();       // https
echo $uri->getUnicodeHost();  // kinsta.com
echo $uri->getAsciiHost();    // kinsta.com
echo $uri->getPath();         // /blog/php-8-5

Les exemples ci-dessus sont les plus basiques. Les deux bibliothèques représentées par l’extension URI dans PHP 8.5 partagent certaines fonctionnalités et présentent également des différences significatives.

Une différence importante est que la bibliothèque RFC 3986 supporte à la fois les représentations « brutes » et « normalisées-décodées » des URI. Cela peut s’avérer utile lorsque vous travaillez avec des entrées et sorties codées en pourcentage. Utilisés dans un navigateur, par exemple, ces deux URI sont identiques :

Dans les versions précédentes de PHP, vous pouviez commencer avec rawurldecode() et rawurlencode() (qui sont également conformes à la RFC 3986), mais la nouvelle extension est prête à travailler avec tous les composants des URI dès le départ, qu’ils soient encodés ou non.

Voici quelques exemples tirés directement de la RFC qui sous-tend la nouvelle API d’analyse :

$uri = new UriRfc3986Uri("https://%61pple:p%61ss@ex%61mple.com/foob%61r?%61bc=%61bc");
  
echo $uri->getRawUserInfo();  // %61pple:p%61ss
echo $uri->getUserInfo();     // apple:pass
 
echo $uri->getRawUsername();  // %61pple
echo $uri->getUsername();     // apple
 
echo $uri->getRawPassword();  // p%61ss
echo $uri->getPassword();     // pass
 
echo $uri->getRawHost();      // ex%61mple.com
echo $uri->getHost();         // example.com
 
echo $uri->getRawPath();      // /foob%61r
echo $uri->getPath();         // /foobar
 
echo $uri->getRawQuery();     // %61bc=%61bc
echo $uri->getQuery();        // abc=abc

Lorsque vous utilisez la bibliothèque URL de WHATWG avec la nouvelle extension, tous les URI sont traités comme « bruts », il n’y a donc pas d’ensemble séparé de fonctions pour prendre en charge un formatage alternatif. Mais la bibliothèque peut convertir les caractères ASCII et Unicode souvent vus dans les URI.

Soyez strict avec la nouvelle directive INI max_memory_limit

On dit qu’un grand pouvoir implique de grandes responsabilités. Si ce pouvoir inclut le choix de la quantité de mémoire serveur que votre application PHP peut essayer d’utiliser, vous pouvez être responsable des plantages de l’application lorsque les processus consomment plus de mémoire que ce qui est disponible.

Une installation typique de PHP comprend un fichier php.ini avec des informations de configuration qui incluent une directive spécifiant une limite de consommation de mémoire pour n’importe quel processus PHP (ou thread). Une directive INI courante pour une limite de mémoire de 128 Mo ressemble à ceci :

// php.ini
memory_limit 128M

Sur certaines plateformes d’hébergement, les développeurs d’applications PHP peuvent remplacer memory_limit à la volée en utilisant la fonction ini_set() dans leur code :

ini_set(‘memory_limit’, ‘256M’);
 
// Start code that requires up to 256 MB of memory

Vous pouvez également donner à la fonction la valeur -1, comme ini_set('memory_limit', '-1') – pour ne pas imposer de limite du tout.

Il peut être risqué pour les développeurs qui ne connaissent pas bien la configuration de la mémoire des serveurs sur lesquels leurs applications sont exécutées de surcharger la directive INI pour une limite de mémoire. Si un ou plusieurs threads PHP tentent de consommer plus que le total de la mémoire disponible, le résultat peut être un plantage de l’application sans avertissement au moment de l’exécution.

PHP 8.5 ajoute une directive max_memory_limit INI qui sert de plafond, même dans les configurations où les développeurs ont accès à init_set() pour ajuster l’utilisation de la mémoire dans leur code.

Voici des exemples d’entrées dans le fichier php.ini d’une installation PHP 8.5 :

// php.ini
max_memory_limit 256M
memory_limit 128M

Avec un max_memory_limit de 256 Mo, voici ce qui se passe dans notre code PHP :

ini_set('memory_limit', '256M');  // This is OK
ini_set('memory_limit', '512M');  // Fail with warning
ini_set('memory_limit', '-1');    // Fail with warning

Si vous tentez de définir une nouvelle limite de mémoire de 512 Mo (ou illimitée), vous n’y parviendrez pas. Au lieu de cela, PHP fixera la limite de mémoire à la valeur assignée à max_memory_limit dans le fichier php.ini et émettra un avertissement. (Le message d’avertissement peut s’afficher à l’écran et être enregistré, en fonction des réglages de signalement des erreurs de l’installation PHP)

Une approche judicieuse pour les développeurs PHP 8.5 serait d’utiliser la fonction ini_get() pour voir si la nouvelle limite maximale a été définie, comme ini_get('max_memory_limit') – et ensuite d’ajuster en fonction de la valeur retournée. Avec les versions de PHP antérieures à la 8.5, cet appel renverrait en toute sécurité false.

Récupérer la première ou la dernière valeur d’un tableau

Levez la main si vous pensiez que PHP avait déjà des fonctions pour lire les valeurs stockées en tant que premier ou dernier membre d’un tableau.

Il s’avère que ce n’est pas le cas. Mais depuis PHP 7.3, il a des fonctions pour découvrir la première et la dernière clé d’ un tableau. Ainsi, pour trouver la première et la dernière valeur, vous pouvez utiliser les fonctions array_key_first() ou array_key_last() et utiliser les clés retournées pour référencer les valeurs que vous recherchez :

$array = ["One", "Two", "Three"];

echo $array[array_key_first($array)]; // "One"

PHP 8.5 élimine une étape pour cette tâche et vous permet d’atteindre les valeurs directement avec les nouvelles fonctions array_first() et array_last().

C’est très simple :

$array = ["One", "Two", "Three"];

echo array_first($array);  // "One"
echo array_last($array);   // "Three"
echo array_last([]);       // null

Ci-dessus, vous pouvez voir qu’un tableau vide renverra null, mais cela ne confirme pas que le tableau entier est vide, puisqu’une valeur de tableau peut être nulle :

echo array_last([1, 2, null]); // null

Rappelez-vous d’utiliser la valeur de retour d’une fonction

PHP 5.8 ajoute un nouvel attribut #[NoDiscard] qui indique que la valeur de retour d’une fonction peut être critique. PHP confirmera que la valeur de retour est consommée d’une manière ou d’une autre et, si ce n’est pas le cas, déclenchera un avertissement.

Un exemple simple :

#[NoDiscard("this message property will be appended to the built-in warning.")]
function foo(): string {
    return 'bar';
}

// Warning:
// The return value of function foo() is expected to be consumed,
// this message property will be appended to the built-in warning.
foo();

// This will not trigger a warning:
$result = foo();

// Also satisfactory is the (void) cast:
(void) foo();

Dans l’exemple ci-dessus, la valeur de retour de la fonction définie n’est pas utilisée du tout dans un premier temps, ce qui déclenche un avertissement. Mais lorsqu’elle est assignée à la variable $result ou castée en void, la valeur est considérée comme consommée.

Les auteurs de la RFC à l’origine de cet ajout à PHP 8.5 ont décrit des utilisations plus convaincantes de cet attribut que le simple exemple ci-dessus. Un des scénarios était une fonction critique avec un rapport d’erreur plus complexe qu’un simple pass/fail, et mieux transmis par la valeur de retour de la fonction.

Autres améliorations liées aux attributs

Outre le nouvel attribut #[NoDiscard], d’autres améliorations ont été apportées à la fonctionnalité des métadonnées d’attributs dans la nouvelle version :

  • Les attributs peuvent désormais cibler des constantes.
  • L’attribut #[Override] peut désormais être appliqué aux propriétés.
  • L’attribut #[Deprecated] peut être utilisé sur les traits et les constantes.
  • Un nouvel attribut #[DelayedTargetValidation] peut être utilisé pour supprimer les erreurs de compilation des attributs de base et d’extension qui sont utilisés sur des cibles non valides.

Dépréciations et suppressions en PHP 8.5

Chaque version de PHP est accompagnée d’une liste de fonctionnalités qui seront supprimées dans les versions futures. L’utilisation de fonctionnalités dépréciées dans votre code déclenchera des avertissements. Lorsqu’elles sont finalement supprimées de PHP, leur utilisation peut entraîner des erreurs fatales.

Voici quelques éléments notables qui sont dépréciés ou supprimés en PHP 8.5 :

  • L’opérateur backtick comme alias de shell_exec() est obsolète.
  • Les noms de cast non canoniques (boolean), (integer), (double), et (binary) ont été dépréciés. Utilisez plutôt (bool), (int), (float), et (string).
  • Le paramètre INI disable_classes a été supprimé car il entraîne la rupture de plusieurs hypothèses du moteur.
  • Terminer les instructions case par un point-virgule au lieu d’un deux-points a été supprimé.
  • L’utilisation de null comme décalage de tableau ou lors de l’appel à array_key_exists() est désormais obsolète. Utilisez plutôt une chaîne vide.
  • Il n’est plus possible d’utiliser « array » et « callable » comme noms d’alias de classe dans class_alias().
  • Les méthodes magiques __sleep() et __wakeup() ont été supprimées. A la place, les méthodes magiques __serialize() et __unserialize() doivent être utilisées.
  • Un avertissement est désormais émis lors du casting de NAN vers d’autres types.
  • La déstructuration de valeurs non-array (autres que null) en utilisant [] ou list() émet maintenant un avertissement.
  • Un avertissement est maintenant émis lors du casting de flottants (ou de chaînes de caractères ressemblant à des flottants) vers int s’ils ne peuvent pas être représentés comme tels.

Résumé

Voilà un aperçu des points forts de la version 8.5 de PHP. Nous sommes convaincus que le nouvel opérateur pipe et l’amélioration de l’analyse des URI seront populaires auprès des développeurs. Peut-être même les nouvelles fonctions array_first() et array_last(), que nous aurions parié sur le fait qu’elles existent déjà.

Mais toute nouvelle version de PHP comprend des centaines de changements. Vous pouvez trouver une liste complète des mises à jour de PHP 8.5 dans le dépôt officiel GitHub du PHP Group.

Pendant ce temps, ici à Kinsta, nous travaillons à rendre PHP 8.5 disponible pour nos clients d’hébergement WordPress. Lorsque cela sera en ligne, vous pourrez passer à la nouvelle version en utilisant nos outils de réglages PHP.

Steve Bonisteel Kinsta

Steve Bonisteel est un rédacteur technique chez Kinsta qui a commencé sa carrière d'écrivain en tant que journaliste de presse écrite, chassant les ambulances et les camions de pompiers. Il couvre les technologies similaires à l'Internet depuis la fin des années 1990.