PHP 8 : qu’est-ce qui change ?

gab_
5 min readNov 25, 2020

--

Photo by Ben on Unsplash

Mon premier talk était pour parler des nouveautés de PHP 7, il s’était fait attendre de nombreuses années et il apportait un vent de nouveautés dans ce langage qui n’avait pas beaucoup évolué. Il apportait surtout une amélioration de performance significative.

Le 26 novembre 2020, la nouvelle version majeure de PHP va sortir, c’est l’occasion de parler des nouveautés et (encore) d’une amélioration des performances.

JIT Compiler

JIT (Just In Time) est un nouveau compilateur qui va permettre d’améliorer les performances de PHP en générant du code natif directement à partir du byte-code PHP. L’amélioration pour certains processus est importante mais pour une application web, la différence n’est pas si grande. Un benchmark a été réalisé ici.

Constructor Property Promotion

C’est surement la fonctionnalité que j’attendais le plus… Une nouvelle syntaxe pour rendre la déclaration d’une propriété plus concise.

Avant il fallait déclarer la propriété puis ajouter un paramètre du constructeur de la classe pour enfin associer le paramètre avec la propriété comme nous pouvons le voir ci-dessous :

class Node
{
protected int $x;
protected int $y;
public function __construct(int $x = 0, int $y = 0) {
$this->x = $x;
$this->y = $y
}
}

Maintenant, il est possible de déclarer la propriété directement dans les paramètres du constructeur :

class Point
{
public function __construct(protected int $x = 0, protected int $y = 0) {}
}

Et voilà ! Il n’y a rien de plus à faire. Le code est plus lisible et nous avons eu à écrire la propriété qu’une seule et unique fois.

Cette méthode fonctionne aussi pour les classes héritées par contre ce n’est pas possible dans les classes et interfaces abstraites.

Union Types

Avant PHP 8, les types d’union ne pouvaient exister que dans les annotations comme par exemple :

class Point {
/**
* @var int|float $x
*/
private $x;

/**
* @param int|float $x
*/
public function setX($x) {
$this->x = $x;
}

/**
* @return int|float
*/
public function getX() {
return $this->x;
}
}

Maintenant, avec PHP 8, les types d’unions sont pris en charge. Ce changement permet d’ajouter plus d’informations dans la signature de la fonction et moins de documentation, c’est important car la syntaxe sera plus stricte, les vérifications plus présentes et donc les erreurs seront détectées plus rapidement.

class Point {
private int|float $x;

public function setX(int|float $x): void {
$this->x = $x;
}
public function getX(): int|float {
return $this->x;
}
}

Il existes quelques contraintes : le void ne pourra pas avoir d’union, le type null ne pourra pas être utilisé de façon autonome (il faudra utiliser ?Type) mais il pourra être utilisé en union (Type|null).

Named Arguments

Il est maintenant possible de passer des arguments d’une fonction avec le nom des paramètres. Ce changement a deux avantages majeurs :

  • Il permet de ne pas mettre les arguments par défaut d’une fonction
  • Il offre la possibilité de mieux documenter son code en offrant une meilleure lisibilité.
// PHP 7
htmlspecialchars($string, default, default, false);
// PHP 8
htmlspecialchars($string, double_encode: false);

Nullsafe operator

L’apparition du nouvel opérateur ?-> va permettre d’éviter de faire des vérifications conditionnelles de nul. Il sera donc possible de faire une chaine d’appel et si l’évaluation d’un élément échoue alors le retour sera null.

L’exemple suivant permet de se rendre compte du gain de code possible :

// PHP 7
$country = null;

if ($session !== null) {
$user = $session->user;

if ($user !== null) {
$address = $user->getAddress();

if ($address !== null) {
$country = $address->country;
}
}
}
// PHP 8
$country = $session?->user?->getAddress()?->country;

Allow trailing comma in parameter list

C’est un détail mais avant PHP 8, il n’était pas possible d’avoir une virgule à la fin de la définition des paramètres d’une fonction alors qu’il était possible d’en avoir pour la liste des arguments de la même fonction. Donc pour gagner en cohérence, c’est maintenant autorisé :

class Uri {
private function __construct(
?string $scheme,
?string $user,
?string $pass,
?string $host,
?int $port,
string $path,
?string $query,
?string $fragment, // <-- OK!
) {
...
}
}
new Uri(
$scheme,
$user,
$pass,
$host,
$port,
$path,
$query,
$fragment, // <-- Already OK!
);

PHP Attributes

Les attributes sont une forme de donnée structurée, qui permet d’ajouter des métadonnées à nos déclarations de classes, propriétés, méthodes, fonctions, paramètres et constantes.

Pour les utilisateurs de Symfony par exemple, les annotations sont des attributs et ils sont utilisés par exemple pour définir une route. Symfony a sorti la version 5.2 qui permet déjà d’utiliser les attributes comme expliqué ici.

Il y a aussi doctrine qui utilise les annotations pour définir la structure d’une table SQL. Cette méthode est semblable à un hack car on va aller parser un docblock non structuré. D’ailleurs, il faut un package doctrine/annotations pour pouvoir lire ces informations…

Donc les nouveaux attributs vont permettre d’avoir une meilleure structure, de ne pas mélanger documentation avec la configuration et d’être plus facile à parser. La syntaxe a changé a plusieurs reprises, elle a été présentée : <<>> puis il y a eu d’autres votes pour modifier cette syntaxe (ici) qui est finalement #[].

str_contains

Avec l’arrivée de PHP 8, viennent de nouvelles fonctions : str_starts_with, str_ends_with, get_debug_type mais aussi str_contains qui me semble être la plus intéressante.

Je ne compte plus le nombre de fois où j’ai cherché comment faire pour savoir si un caractère était dans une chaine de caractères pour finalement trouver cette méthode qui me semblait pas totalement adaptée :

if (strpos('le nouveau php 8 est sorti', 'php') !== false) {
echo 'Trouvé';
} else {
echo 'Pas trouvé';
}

Et maintenant, nous pouvons écrire un code plus lisible :

if (str_contains('le nouveau php 8 est sorti', 'php')) {
echo 'Trouvé';
} else {
echo 'Pas trouvé';
}

Il faut savoir deux choses : cette fonction n’est pas sensible à la casse pour le moment et si nous cherchons un caractère vide (''), le résultat sera toujours true.

C’est la fin de cet article, je pense avoir fait le tour des principales nouveautés de PHP 8. J’ai hâte de mettre à jour les projets en Symfony de Kinoba en mettant en place rapidement la fonction str_contains et les attributs. Pour découvrir certains de mes développements, c’est par ici.

--

--

gab_
gab_

Written by gab_

Co-founder of Kinoba, a web agency located in Lyon. Symfony developer, PHP lover. #Symfony #development #php

No responses yet