PHP 8.1 - Les nouveautés  9 min  

PHP 8.1 est actuellement en développement actif et sera publié le 25 novembre 2021. Gardez à l'esprit que cette date peut encore changer si l'équipe centrale, par exemple, ajoute une version bêta supplémentaire. Nous connaissons déjà les nouvelles fonctionnalités, les améliorations de performance, les changements et les dépréciations ; alors passons-les en revue une par une.

Nouvelles fonctionnalités

Comme pour chaque version, PHP 8.1 ajoute quelques nouvelles fonctionnalités. Gardez à l'esprit que cette liste s'allongera au cours de l'année.

Enums 

Les Enums seront ajoutés en PHP 8.1 ! Si vous ne savez pas à quoi ils peuvent servir, vous pouvez lire ce qui les concerne ici.
L'ajout des enums serait une amélioration significative de PHP. Pour vous donner un aperçu rapide de ce à quoi ils ressembleront, voici un exemple de code :

enum Status {
  case Pending;
  case Active;
  case Archived;
}

Et c'est ainsi qu'ils seront utilisés :

class Post
{
    public function __construct(
        private Status $status = Status::Pending;
    ) {}

    public function setStatus(Status $status): void
    {
        // …
    }
}

$post->setStatus(Status::Active);

 

Fiber

Les fiber - alias "green threads" - sont un mécanisme de bas niveau pour gérer le parallélisme. Vous ne les utiliserez probablement pas directement dans vos applications, mais des frameworks comme Amphp et ReactPHP en feront un usage intensif.

Voici un exemple simple d'utilisation de fiber :

$fiber = new Fiber(function (): void {
    $valueAfterResuming = Fiber::suspend('after suspending');
    
    // … 
});
 
$valueAfterSuspending = $fiber->start();
 
$fiber->resume('after resuming');

Améliorations des performances

Dmitry Stogov a ajouté quelques améliorations à opcache, il l'appelle "inheritance cache". Cette fonctionnalité permet de mettre en cache les liens entre les classes, un peu comme les classes liées peuvent être préchargées depuis PHP 7.4.

Dmitry rapporte une augmentation des performances de 5% à 8% grâce à ce changement, un petit détail intéressant à surveiller en PHP 8.1.

Décompression de tableaux avec des clés de chaînes

Le déballage de tableaux était déjà autorisé en PHP 7.4, mais il ne fonctionnait qu'avec des clés numériques. La raison pour laquelle les chaînes de caractères n'étaient pas supportées auparavant est qu'il n'y avait pas de consensus sur la façon de fusionner les doublons de tableaux. La RFC résout proprement ce problème en suivant la sémantique de array_merge :

$array1 = ["a" => 1];

$array2 = ["b" => 2];

$array = ["a" => 0, ...$array1, ...$array2];

var_dump($array); // ["a" => 1, "b" => 2]

dans les initialisateurs Nouveau

Ce RFC vous permet d'utiliser le mot clé new dans les définitions de fonctions comme paramètre par défaut, ainsi que dans les arguments d'attributs et à d'autres endroits.

class MyController {
    public function __construct(
        private Logger $logger = new NullLogger(),
    ) {}
}

Propriétés en lecture seule

Les propriétés des classes peuvent être marquées comme étant en lecture seule, ce qui signifie qu'elles ne peuvent être écrites qu'une seule fois.

class PostData {
    public function __construct(
        public readonly string $title,
        public readonly DateTimeImmutable $date,
    ) {}
}

Si vous essayez de modifier une propriété en lecture seule après qu'elle a été initialisée, vous obtiendrez une erreur :

$post = new Post('Title', /* … */);

$post->title = 'Other';

Error: Cannot modify readonly property Post::$title

Syntaxe des appels de première class
Vous pouvez maintenant créer une fermeture à partir d'un appelant en appelant cet appelant et en lui passant ... comme argument :

function foo(int $a, int $b) { /* … */ }

$foo = foo(...);

$foo(a: 1, b: 2);

Types d'intersection purs

Vous connaissez déjà les types union en PHP 8.0, et les types intersection sont une fonctionnalité similaire. Alors que les types union requièrent que l'entrée soit un des types donnés, les types intersection requièrent que l'entrée soit tous les types spécifiés. Les types d'intersection sont particulièrement utiles lorsque vous travaillez avec de nombreuses interfaces :

function generateSlug(HasTitle&HasId $post) {
    return strtolower($post->getTitle()) . $post->getId();
}

Si vous aimez ce style de programmation, vous devrez créer une nouvelle interface Sluggable et l'implémenter dans $post, les types d'intersection se débarrassant de cette surcharge.

Nouveau type never

Le type never peut être utilisé pour indiquer qu'une fonction va réellement arrêter le déroulement du programme. Cela peut être fait en lançant une exception, en appelant exit ou d'autres fonctions similaires.

function dd(mixed $input): never
{
    // dump
    
    exit;
}

never diffère de void en ce sens que void permet toujours au programme de continuer. Cela peut sembler être une nouveauté, mais c'est en fait une fonctionnalité très utile pour les analyseurs statiques.

Nouvelle fonction array_is_list

Vous avez probablement eu à faire face à cette fonction de temps en temps : déterminer si les clés d'un tableau sont dans l'ordre numérique, en commençant par l'indice 0. Tout comme json_encode décide si un tableau doit être encodé comme un tableau ou un objet.

PHP 8.1 ajoute une fonction intégrée pour déterminer si un tableau est une liste avec cette sémantique, ou non :

$list = ["a", "b", "c"];

array_is_list($list); // true

$notAList = [1 => "a", 2 => "b", 3 => "c"];

array_is_list($notAList); // false

$alsoNotAList = ["a" => "a", "b" => "b", "c" => "c"];

array_is_list($alsoNotAList); // false

Constantes de classe finales

Les constantes de classe en PHP peuvent être surchargées lors de l'héritage :

class Foo
{
    public const X = "foo";
}
 
class Bar extends Foo
{
    public const X = "bar";
}

Depuis PHP 8.1, vous pouvez marquer ces constantes comme finales afin d'éviter cela :

class Foo
{
    final public const X = "foo";
}
 
class Bar extends Foo
{
    public const X = "bar";
    
Fatal error: Bar::X cannot override final constant Foo::X

}

Nouvelle fonction fsync

PHP 8.1 ajoute les fonctions fsync et fdatasync pour forcer la synchronisation des changements de fichiers sur le disque et s'assurer que les tampons d'écriture du système d'exploitation ont été vidés avant de revenir.

$file = fopen("sample.txt", "w");

fwrite($file, "Some content");

if (fsync($file)) {
    echo "File has been successfully persisted to disk.";
}

fclose($file);

La synchronisation des disques étant une opération du système de fichiers, la fonction fsync ne fonctionnera que sur les flux de fichiers ordinaires. Tenter de synchroniser des flux non-fichiers émettra un avertissement.

Notation littérale explicite des nombres entiers octaux

Vous pouvez maintenant utiliser 0o et 0O pour désigner des nombres octaux. La notation précédente en préfixant un nombre avec 0 fonctionne toujours.

016 === 0o16; // true
016 === 0O16; // true

Derniers changements

Bien que PHP 8.1 soit une version mineure, il y aura quelques changements qui pourraient techniquement être des changements de rupture, ainsi que des dépréciations. Voyons-les un par un.

Restreindre l'utilisation de $GLOBALS

Un petit changement dans la façon dont $GLOBALS est utilisé aura un impact significatif sur les performances de toutes les opérations sur les tableaux. Nikita fait un excellent travail en expliquant le problème et la solution dans la RFC. Le changement signifie que certains cas limites ne sont plus possibles avec $GLOBALS. "Ce qui n'est plus supporté, ce sont les écritures dans $GLOBALS prises dans leur ensemble. Tout ce qui suit générera une erreur de compilation" :

$GLOBALS = [];
$GLOBALS += [];
$GLOBALS =& $x;
$x =& $GLOBALS;
unset($GLOBALS);

En plus de cela, le fait de passer $GLOBALS par référence générera une erreur d'exécution :

by_ref($GLOBALS); // Run-time error

Nikita a analysé les 2000 premiers paquets sur Packagist, et a trouvé seulement 23 cas qui seront affectés par ce changement. Nous pouvons conclure que l'impact de ce changement - techniquement cassant - sera faible, ce qui explique pourquoi les internes ont décidé de l'ajouter dans PHP 8.1. Rappelez-vous que la plupart d'entre nous seront gagnants par ce changement, étant donné l'impact positif sur les performances qu'il a partout dans notre code.

Migration des ressources vers les objets

Ces changements font partie de la vision à long terme de convertir toutes les ressources en objets dédiés. Vous pouvez en savoir plus à ce sujet ici.

Fonctions fileinfo avec objets finfo

Les fonctions comme finfo_file et finfo_open acceptaient et retournaient des ressources. Depuis PHP 8.1, elles fonctionnent avec les objets finfo.

Fonctions IMAP avec les objets IMAPConnection

Tout comme le changement de fileinfo, les fonctions IMAP comme imap_body et imap_open ne fonctionnent plus avec les ressources.

Déprogrammer le passage de null aux arguments non-nullables des fonctions internes rfc

Ce changement est simple : les fonctions internes acceptent actuellement null pour les arguments qui sont non-nullables, ce RFC déprécie ce comportement. Par exemple, ceci est actuellement possible :

str_contains("string", null) ;

En PHP 8.1, ce type d'erreur génère un avertissement de dépréciation, en PHP 9, il sera converti en erreur de type.

Autovivification sur fausse

Extrait de la RFC :

PHP permet nativement l'autovivification (auto-création de tableaux à partir de valeurs fausses). Cette fonctionnalité est très utile et utilisée dans de nombreux projets PHP, surtout si la variable est indéfinie. Cependant, il existe une petite bizarrerie qui permet de créer un tableau à partir d'une valeur fausse et nulle.

Vous pouvez lire les détails sur la page de la RFC. En résumé, ce comportement est déprécié :

$array = false;

$array[] = 2;

Automatic conversion of false to array is deprecated

Autres petits changements

Avec chaque version, il y a un tas de changements très mineurs dans le langage. Toutes sont listées dans le guide UPGRADING sur GitHub et dans la petite RFC de dépréciation, assurez-vous de la consulter si vous voulez connaître chaque petit détail.

Voici un résumé des changements les plus importants :

  1. MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH n'a plus d'effet.
  2. MYSQLI_STORE_RESULT_COPY_DATA n'a plus d'effet.
  3. PDO::ATTR_STRINGIFY_FETCHES fonctionne désormais également avec les booléens.
  4. Les entiers et les flottants dans les jeux de résultats PDO MySQL et Sqlite seront retournés en utilisant les types PHP natifs au lieu des chaînes de caractères lors de l'utilisation d'instructions préparées émulées.
  5. Les fonctions comme htmlspecialchars et htmlentities échappent maintenant ' par défaut à ' les UTF-8 mal formés seront également remplacés par un caractère unicode, au lieu de donner une chaîne vide.
  6. Un argument supplémentaire appelé $options a été ajouté aux fonctions hash, hash_file et hash_init. Sa valeur par défaut est [] et n'affectera donc pas votre code.
  7. Nouveau support pour MurmurHash3 et xxHash

Auteur

KilioZ

Étudiant en BTS Travaux Publics au Pas-de-Calais. Fondateur de Dev-Time, développeur web depuis 2013.


  Discord : Mateo M.#6452   Reddit : KilioZDev