Nouveautés de PHP 7.3 🐘

La nouvelle version de PHP est sortie le 06 décembre 2018, découvrons ensemble les nouveautés de PHP 7.3.

Environnement de test

Avant de commencer, nous allons voir rapidement comment tester différentes versions de PHP. Voyons comment installer parallèlement PHP 7.3 et PHP 7.2 (qui nous servira de référence). La procédure ci-dessous a été faite sous Windows pour le plus grand nombre mais peut être menée sous Linux ou MacOS.

Nous allons ensuite extraire chaque archive dans un dossier différent :

  • Créer un dossier /PHP7.2/ et y placer le contenu de l’archive PHP 7.2
  • Créer un dossier /PHP7.3/ et y placer le contenu de l’archive PHP 7.3
  • Créer un dossier /src/ dans lequel vous pouvez mettre vos scripts de test.

Nous pouvons maintenant démarrer notre serveur de test PHP 7.2 grâce au serveur web intégré à PHP. Dans l’invite de commande, lançons un premier serveur web sur http://localhost:8072

\PHP7.2\php.exe -t src\ -S localhost:8072

Lançons un serveur de test PHP 7.3 sur un numéro de port différent dans une seconde invite de commande. Le serveur PHP 7.3 sera accessible à l’adresse http://localhost:8073

\PHP7.3\php.exe -t src\ -S localhost:8073

Nous sommes maintenant près à dépiler les fonctionnalités décrites dans les RFC de PHP 7.3 : https://wiki.php.net/rfc#php_73

Syntaxes Heredoc et Nowdoc plus flexibles

RFC : https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes
Documentation : http://php.net/manual/fr/language.types.string.php#language.types.string.syntax.heredoc

En PHP, il existe de nombreuses manières de déclarer des chaines de caractères, des string . Vous connaissez les apostrophes simples, les doubles apostrophes, mais connaissez-vous les syntaxes Heredoc et Nowdoc ? Ces syntaxes un peu plus lourde que l’apostrophe vous évitent justement d’avoir à échapper les apostrophes et sont particulièrement adaptées aux chaines sur plusieurs lignes . Toutefois, leur syntaxe particulière peuvent en dérouter quelques-uns, prenons l’exemple avec heredoc :

class Query
{
	public $sql = <<<SQL
		SELECT *
		FROM User
		WHERE name = 'Joe';
SQL;
}

Dans l’exemple précédent, on peut voir que l’opérateur <<< est suivi d’un identifiant, j’ai choisi SQL. Pour fermer la chaine, jusqu’en PHP 7.2, vous deviez écrire l’identifiant à la ligne (collé à gauche). Heureusement, cette syntaxe gagne en flexibilité avec PHP 7.3 et permet d’indenter l’identifiant de fin.

class Query
{
	public $sql = <<<SQL
		SELECT *
		FROM User
		WHERE name = 'Joe';
	SQL;
}

Virgule de fin dans l’appel de fonction autorisée

RFC : https://wiki.php.net/rfc/trailing-comma-function-calls

En PHP, il est possible de laisser trainer une virgule à la fin de la liste des éléments dans un Array
PHP 7,2 étendait cette possibilité aux espaces de noms groupés

use Framework\Component\{
    Email,
    Console,
    Log,
};

Grâce à PHP 7.3, il est maintenant possible d’utiliser cette syntaxe lors de l’appel d’une fonction. La virgule de fin qui générait une erreur en PHP 7.2 est valide en PHP 7.3.

var_dump(
    'CODE',
    'DESIGN',
);

Configurer l’extension JSON pour lancer une exception en cas d’erreur

RFC : https://wiki.php.net/rfc/json_throw_on_error
Documentation : http://php.net/manual/fr/function.json-decode.php

Avec PHP 7.2, la fonction json_decode() retournait NULL en cas d’erreur ce qui pouvait porter à confusion car NULL peut également être une valeur valide. Il était d’ailleurs possible de récupérer l’erreur avec les fonctions json_last_error() et json_last_error_msg().

Depuis PHP 7.3, la flag JSON_THROW_ON_ERROR permet de modifier la gestion d’erreur des fonctions JSON en envoyant une exception de type JsonException pouvant être gérée dans un try{} catch{}.

$json = '{"title":"code|design.fr"}s';

try {
    $title = json_decode($json, false, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $exception) {
    echo $exception->getMessage();
}

Affectation par référence avec la fonction list()

RFC : https://wiki.php.net/rfc/list_reference_assignment
Documentation : http://php.net/manual/fr/function.list.php, http://php.net/manual/fr/language.references.php

En PHP, une référence est une manière d’accéder au contenu d’une variable en utilisant différent noms. Par défaut, l’affectation d’une instance d’un objet en PHP se fait par référence tandis que l’affectation d’une chaine de caractères se fait par copie. Pour forcer le passage par référence d’une chaine de caractère, il faut préfixer la variable par  &.

Toutefois, avec PHP 7.2, il n’était pas possible d’éclater les valeurs d’un tableau avec la fonction list() pour les récupérer par référence. C’est maintenant possible avec PHP 7.3.

$languages = ['PHP', 'JAVA', 'SQL'];

// Affecte chaque valeur du tableau à une variable par référence
list(&$a, &$b, &$c) = $languages;

// Modifie $b par référence
$b = 'JavaScript';

// Affiche les valeurs du tableau initial
print_r($languages); // Array ( [0] => PHP [1] => JavaScript [2] => SQL )

Nouvelle fonction is_countable()

RFC : https://wiki.php.net/rfc/is-countable
Documentation : http://php.net/manual/fr/function.is-countable.php

La fonction count() renvoie une erreur si le paramètre qui lui est passé n’est pas énumérable. En PHP 7.3, la fonction is_countable() fait son apparition afin de vérifier que la valeur est énumérable avant de réaliser un comptage.

$instance = new stdClass();

if(is_countable($instance)){
    $size = count($instance);
}

Nouvelles fonction array_key_first() et array_key_last()

RFC : https://wiki.php.net/rfc/array_key_first_last
Documentation : http://php.net/manual/fr/function.array-key-first.php, http://php.net/manual/fr/function.array-key-last.php

En PHP 7.2, pour récupérer la première ou dernière clé d’un tableau, vous deviez enchainer plusieurs fonctions de manipulation de tableau tel que  key(), reset() ou autre hack.

PHP 7.3 introduit deux nouvelles fonctions array_key_first() et array_key_last().

$languages = [
   7 => 'PHP',
   14 => 'HTML',
   22 => 'CSS'
];
// Récupère l'ID du 1er langage de la liste
$firstLanguageKey = array_key_first($languages);

var_dump($firstLanguageKey); // int(1) 7

Amélioration de l’algorithme de hachage Argon2 avec l’ajout de Argon2id

RFC : https://wiki.php.net/rfc/argon2_password_hash_enhancements
Documentation : http://php.net/manual/fr/function.password-hash.php, http://php.net/manual/fr/password.constants.php

PHP fourni toute une panoplie de fonction de cryptographie dont certaines sont spécifiques au hachage de mot de passe.

Depuis PHP 5.5, la fonction password_hash() permet de « sécurisé » un mot de passe en le transformant de telle sorte que l’on puisse continuer de le vérifier avec password_verify() sans jamais pouvoir en retrouver sa valeur d’origine.

Pour utiliser ces fonctions de hachage, vous devez choisir un algorithme à utiliser. Chaque algorithme à des spécificités comme leur vitesse d’exécution et leur niveau de sécurité. Par défaut, la constante 
PASSWORD_DEFAULT permet de choisir automatiquement l’algorithme conseillé. Bien que cette constante continuera d’appliquer 
PASSWORD_BCRYPT, depuis PHP 7.2, vous pouvez opter pour
PASSWORD_ARGON2I qui se veut être le prochain standard à venir.

En PHP 7.3, l’algorithme Argon2 introduit une nouvelle variante qui est recommandée car un mix entre Argon2i et Argon2d, le Argon2id via la nouvelle constante PASSWORD_ARGON2ID.

A noter que vous pouvez migrer de Bcrypt à Argon2 sans problème. En effet, la valeur que vous avez stocké en base de données contient une empreinte du mot de passe, mais également l’algorithme utilisé. La fonction
password_verify() fera automatiquement la différence entre des mots de passe utilisant Bcrypt et des mots de passe utilisant Argon2.

Pour aller plus loin

PHP 7.3 intègre de nombreux autres changements. Si le sujet vous intéresse, n’hésitez pas à vous référer au guide de migration PHP 7.2 vers PHP 7.3 : http://php.net/manual/en/migration73.php

Ressources récentes