Tutoriel Vidéo PHP Les nouveautés de PHP 7.1

Télécharger la vidéo

La version 7.1 de PHP est une mise à jour qui vient consolider certains apports de la version 7.0 consolidant par exemple le système de typage. L'ensemble des changements apportés sont visibles sur la documentation mais je vous propose de faire un petit tour d'horizon des changements importants qui selon moi justifient la migration vers cette nouvelle version.

Les types nullable

PHP 7.0 a apporté la possibilité de typer les paramètres et les retours de fonctions. Par contre dans certains cas (par exemple une requête SQL) nos fonctions ne retourne aucun résultat. Ce type de retour peut maintenant être décrit en précédent le type d'un "?" pour spécifier un retour "parfois null".

/**
* Permet de récupérer un enregistrement par son ID
**/
public function find(int $id = null): ?array
{
  $query = $this->pdo->prepare('SELECT * FROM id WHERE id = ?');
  $query->execute([$id]);
  return $query->fetch() ?: null;
}

Le type void

De la même façon il est possible de spécifier qu'une fonction ne retourne rien gràce au type void.

public function crier(string $words): void
{
    echo strtoupper($words);
}

Attention cependant, même si le retour d'une fonction est désigné comme void, une fonction sans retour continuera de retourner null si appelée.

$a = crier('Salut'); // Affichera "SALUT";
var_dump($a); // null

Le type iterable

Un nouveau pseudo-type a été introduit pour désigner une variable que l'on peut parcourir à travers un foreach. Ce pseudo-type peut être utilisé pour représenter un tableau ou une classe qui implémente l'interface Traversable.

function showLi(iterable $items): void
{
    foreach ($items as $item) {
        echo "<li>" . $item . "</li>"
    }
}

L'arrivé de ce peusdo-type est accompagné d'une nouvelle fonction is_iterable qui, comme son nom l'indique, permet de tester si une variable est iterable.

var_dump(is_iterable([1, 2, 3]));  // bool(true)
var_dump(is_iterable(new ArrayIterator([1, 2, 3])));  // bool(true)
var_dump(is_iterable((function () { yield 1; })()));  // bool(true)
var_dump(is_iterable(1));  // bool(false)
var_dump(is_iterable(new stdClass()));  // bool(false)

Création d'une closure depuis un callable

Si une de vos fonction attend une closure et que vous souhaitez lui passer un callable, vous pouvez utiliser la méthode static fromCallable() pour convertir votre variable.

function crier(closure $closure): string
{
  return strtoupper($closure());
}

class Demo
{
  public function hello(): string
  {
    return "Salut";
  }
}

$demo = new Demo();
crier(Closure::fromCallable([$demo, "hello"]));

Le catch() de plusieurs exceptions

Il est maintenant possible de spécifier plusieurs types d'exceptions à capturer grâce au caractère pipe |.

try {
  // ...
} catch (\Throwable | \MyException $e) {

}

Cela permettra de gagner quelques lignes dans certaines situations.

La destructuration de tableau

La syntaxe courte pour les tableau [] peut maintenant être utilisée pour l'assignement de variable comme alternative à la fonction list(). Cette nouvelle syntaxe peut s'utiliser dans les foreach mais ne peut pas s'utiliser dans les arguments d'une fonction.

$persons = [
  [1, "John"],
  [2, "Marc"]
];

// avec la fonction list()
list($id, $name) = $persons[0];

// Nouvelle syntaxe
[$id, $name] = $persons[0];

// Dans un foreach
foreach ($persons as [$id, $name]) {
  // ...
}

// /!\ Ne marche pas dans les arguments de fonctions !
function a([$id, $name]) {} // Syntax Error
// Il faudra écrire
function b($person) {
  [$id, $name] = $person;
}

La fonction list, et cette nouvelle syntaxe, supporte aussi l'utilisation de clefs

$data = [
    ["id" => 1, "name" => 'Tom'],
    ["id" => 2, "name" => 'Fred'],
];

list("id" => $id1, "name" => $name1) = $data[0];
["id" => $id1, "name" => $name1] = $data[0];

// dans un foreach
foreach ($data as ["id" => $id, "name" => $name]) {
    // ...
}

Cela peut s'avérer intéréssant si combiné avec des fonctions qui ont un retour prévisible.

$path = "/mon/dossier/image.jpg";
["filename" => $filename, "extension" => $extension] = pathinfo($path);
echo $filename . '_thumb.' . $extension; // image_thumb.jpg

Visibilité des constantes

Plus anecdotique, il est maintenant possible de préciser la visibilité des constantes d'une classe.

class Demo
{
    const PUBLIC_CONST_A = 1;
    public const PUBLIC_CONST_B = 2;
    protected const PROTECTED_CONST = 3;
    private const PRIVATE_CONST = 4;
}

Offset négatif pour les chaînes

Les fonctions de manipulation de chaînes de caractères supportent maintenant les offsets négatifs.

var_dump("abcdef"[-2]);  // string (1) "e"
var_dump(strpos("aabbcc", "b", -3)); // int(3)

Autres changements

Enfin, pour finir cette nouvelle version change certaines choses qui pourraient avoir un effet sur votre code donc n'hésitez pas à faire un tour sur la liste des changements qui cassent la compatibilité.

  • L'extension mcrypt est maintenant dépréciée au profit de l'extension openssl.

  • Une fonction appellée avec un nombre insufissant de paramètres ne renvoie plus un warning mais une Exception.

  • Certaines fonctions ne peuvent plus être appellées dynamiquement (avec le format $func(), array_map('extract', $array)).

  • Il n'est plus possible de nommer une classe, un trait ou une interface void ou iterable.

  • L'algorithme de génération de nombres a été changé et affecte les fonctions shuffle(), rand() et autre.

  • Les classes DateTime et DateTimeImmutable utilisent maintenant les microsecondes quand l'objet est construit depuis une date relative ou depuis la date du jour.

    // Peut du coup retourner false
    new DateTime() == new DateTime(); 
    
  • L'opcache est maintenant activé par défaut en mode cli `opcache.enable_cli=1

Encore une fois, n'hésitez pas à vous rendre sur le guide de migration pour voir la totalité des changements.