PHP 8.4.1 Released!

Nouvelles fonctionnalités

Cœur de PHP

Propriétés typées

Les propriétés des classes supportent désormais la déclaration du type.

<?php
class User {
public
int $id;
public
string $name;
}
?>
L'exemple ci-dessus s'assurera que $user->id ne peut se voir attribuer que des valeurs d'entier et $user->name ne peut se voir attribuer que des valeurs chaîne de caractères.

Fonctions flèches

Les fonctions flèches fournissent une syntaxe courte pour définir des fonctions qui lient la portée par valeur implicitement.

<?php
$factor
= 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);
?>

Type de retour covariant et type d'argument contravariant limité

Le code suivant va désormais fonctionner :

<?php
class A {}
class
B extends A {}

class
Producer {
public function
method(): A {}
}
class
ChildProducer extends Producer {
public function
method(): B {}
}
?>
Le support de variance totale est seulement disponible quand l'autoloading est utilisé. Dans un fichier unique seules des références de types non cycliques sont possibles, car toutes les classes doivent être disponibles avant qu'elles soient référencées.

Opérateur d'assignement de fusion Null

<?php
$array
['key'] ??= computeDefault();
// is roughly equivalent to
if (!isset($array['key'])) {
$array['key'] = computeDefault();
}
?>

Déballage dans les tableaux

<?php
$parts
= ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
?>

Séparateur numérique litéral

Les nombres littéraux peuvent contenir un caractère de soulignement entre les chiffres.

<?php
6.674_083e-11
; // float
299_792_458; // decimal
0xCAFE_F00D; // hexadecimal
0b0101_1111; // binary
?>

Références faibles

Les références faibles permettent au développeur de retenir une référence à un objet qui n'empêche pas l'objet d'être détruit.

Autoriser des Exceptions depuis __toString()

Lancer des exceptions depuis __toString() est désormais permis. Précédemment, ceci résultait en une erreur fatale. Les erreurs fatales récupérables dans les conversions de chaîne de caractères ont été converties en exceptions Error.

CURL

CURLFile supporte désormais les enveloppes de flux en plus des noms de fichiers bruts, si l'extension a été compilée avec libcurl >= 7.56.0.

Filtre

Le filtre FILTER_VALIDATE_FLOAT supporte désormais les options min_range et max_range, avec la même sémantique que FILTER_VALIDATE_INT.

FFI

FFI est une nouvelle extension, qui fournit une manière simple d'appeler les fonctions natives, un accès natif aux variables, et la création/l'accès à des structures de données définies dans des bibliothèques C.

GD

Ajout du filtre d'image IMG_FILTER_SCATTER pour appliquer un filtre à dispersions aux images.

Hash

Ajout du hash crc32c utilisant le polynôme de Castagnoli. Cette variante de CRC32 est utilisée par les systèmes de stockage, tels que iSCSI, SCTP, Btrfs et ext4.

Chaînes multioctets

Ajout de la fonction mb_str_split(), qui fournit la même fonctionnalité que str_split(), mais opère sur des points de code au lieu d'octets.

Expressions Régulières (Compatible Perl)

Les fonctions preg_replace_callback() et preg_replace_callback_array() acceptent désormais un argument flags additionnel, avec le support des drapeaux PREG_OFFSET_CAPTURE et PREG_UNMATCHED_AS_NULL. Ceci influence le format du tableau de matchs passé à la fonction de rappel.

PDO

Le nom d'utilisateur et le mot de passe peuvent désormais être spécifiés en tant que partie du DSN PDO pour les pilotes mysql, mssql, sybase, dblib, firebird et oci. Précédemment, ceci était seulement supporté pour le pilote pgsql. Si un nom d'utilisateur/mot de passe est défini à la fois dans le constructeur et le DSN, le constructeur prend précédence.

Il est désormais possible d'échapper les points d'interrogations dans les requêtes SQL pour éviter qu'ils ne soient interprétés comme paramètre fictif. Écrire ?? permet d'envoyer un seul point d'interrogation à la base de données et, par exemple, utiliser l'opérateur PostgreSQL JSON pour savoir si une clef existe (?).

PDO_OCI

PDOStatement::getColumnMeta() est désormais disponible.

PDO_SQLite

PDOStatement::getAttribute(PDO::SQLITE_ATTR_READONLY_STATEMENT) permet de vérifier si la déclaration est en lecture seule, c.à.d. si elle ne modifie pas la base de données.

PDO::setAttribute(PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES, true) active l'utilisation des codes de résultats étendus dans PDO::errorInfo() et PDOStatement::errorInfo().

SQLite3

Ajout de SQLite3::lastExtendedErrorCode() pour récupérer le dernier code étendu du résultat.

Ajout de SQLite3::enableExtendedResultCodes($enable = true), qui fera retourner des codes de résultats étendus par SQLite3::lastErrorCode().

Standard

strip_tags() avec un tableau de noms de tag

strip_tags() accepte désormais un tableau de tags autorisés : au lieu de strip_tags($str, '<a><p>') il est désormais possible d'écrire strip_tags($str, ['a', 'p']).

Sérialisation personnalisée d'objets

Un nouveau mécanisme de sérialisation personnalisée d'objets a été ajouté, qui utilise deux nouvelles méthodes magiques : __serialize et __unserialize.

<?php
// Retourne un tableau contenant tout l'état nécessaire de l'objet.
public function __serialize(): array;

// Restaure l'état d'un objet depuis le tableau de données fourni.
public function __unserialize(array $data): void;
?>
Le nouveau mécanisme de sérialisation succèdera à l'interface Serializable, qui sera rendu obsolète dans le futur.

Les fonctions array merge sans arguments

array_merge() et array_merge_recursive() peuvent désormais être appelées sans arguments, dans ce cas-là elles retourneront un tableau vide. Ceci est utile en conjonction avec l'opérateur de décomposition, par exemple array_merge(...$arrays).

La fonction proc_open()

proc_open() accepte désormais un tableau au lieu d'une chaîne de caractères pour la commande. Dans ce cas-là, le processus est ouvert directement (sans passer à travers un shell) et PHP s'occupera d'échapper les arguments lorsque nécessaire.

<?php
proc_open
(['php', '-r', 'echo "Hello World\n";'], $descriptors, $pipes);
?>

proc_open() supporte désormais les descripteurs redirect et null.

<?php
// Like 2>&1 on the shell
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['redirect', 1]], $pipes);
// Like 2>/dev/null or 2>nul on the shell
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['null']], $pipes);
?>

argon2i(d) sans libargon

password_hash() a désormais les implémentations de argon2i et argon2id de l'extension sodium quand PHP est compilé sans libargon.

add a note

User Contributed Notes 2 notes

up
98
Rain
4 years ago
It should be noted that typed properties internally are never initialized to a default null. Unless of course you initialize them to null yourself. That's why you will always going to encounter this error if you try to access them before initialization.

**Typed property foo::$bar must not be accessed before initialization**

<?php
class User
{
public
$id;
public
string $name; // Typed property (Uninitialized)
public ?string $age = null; // Typed property (Initialized)
}

$user = new User;
var_dump(is_null($user->id)); // bool(true)
var_dump(is_null($user->name)); // PHP Fatal error: Typed property User::$name must not be accessed before initialization
var_dump(is_null($user->age));// bool(true)
?>

Another thing worth noting is that it's not possible to initialize a property of type object to anything other than null. Since the evaluation of properties happens at compile-time and object instantiation happens at runtime. One last thing, callable type is not supported due to its context-dependent behavior.
up
7
wow-apps.pro
4 years ago
<?php

// How to get property type? For example for testing:

class Foo
{
private
int $num;
private
bool $isPositive;
private
$notes;
}

$reflection = new \ReflectionClass(Foo::class);
$classProperties = $reflection->getProperties(\ReflectionProperty::IS_PRIVATE);
foreach (
$classProperties as $classProperty) {
var_dump((string) $classProperty->getType());
}

/**
* Result:
* "int"
* "bool"
* ""
*/
To Top