PHP 8.4.1 Released!
Released!
PHP 8.4 est une mise à jour majeure du langage PHP.
Elle introduit de nombreuses nouvelles fonctionnalités, telles que les hooks de propriétés, la visibilité asymétrique, une API DOM mise à jour, des améliorations de performances, des corrections de bugs et un nettoyage général.

Hooks de propriété RFC Doc

PHP < 8.4
class Locale
{
private
string $languageCode;
private
string $countryCode;

public function
__construct(string $languageCode, string $countryCode)
{
$this->setLanguageCode($languageCode);
$this->setCountryCode($countryCode);
}

public function
getLanguageCode(): string
{
return
$this->languageCode;
}

public function
setLanguageCode(string $languageCode): void
{
$this->languageCode = $languageCode;
}

public function
getCountryCode(): string
{
return
$this->countryCode;
}

public function
setCountryCode(string $countryCode): void
{
$this->countryCode = strtoupper($countryCode);
}

public function
setCombinedCode(string $combinedCode): void
{
[
$languageCode, $countryCode] = explode('_', $combinedCode, 2);

$this->setLanguageCode($languageCode);
$this->setCountryCode($countryCode);
}

public function
getCombinedCode(): string
{
return
\sprintf("%s_%s", $this->languageCode, $this->countryCode);
}
}

$brazilianPortuguese = new Locale('pt', 'br');
var_dump($brazilianPortuguese->getCountryCode()); // BR
var_dump($brazilianPortuguese->getCombinedCode()); // pt_BR
PHP 8.4
class Locale
{
public
string $languageCode;

public
string $countryCode
{
set (string $countryCode) {
$this->countryCode = strtoupper($countryCode);
}
}

public
string $combinedCode
{
get => \sprintf("%s_%s", $this->languageCode, $this->countryCode);
set (string $value) {
[
$this->countryCode, $this->languageCode] = explode('_', $value, 2);
}
}

public function
__construct(string $languageCode, string $countryCode)
{
$this->languageCode = $languageCode;
$this->countryCode = $countryCode;
}
}

$brazilianPortuguese = new Locale('pt', 'br');
var_dump($brazilianPortuguese->countryCode); // BR
var_dump($brazilianPortuguese->combinedCode); // pt_BR
Les hooks de propriété offrent un support pour les propriétés calculées, compréhensibles nativement par les IDE et les outils d'analyse statique, sans avoir besoin d'écrire des commentaires docblock susceptibles de devenir obsolètes. De plus, ils permettent un pré- ou post-traitement fiable des valeurs, sans avoir à vérifier l'existence d'un getter ou d'un setter correspondant dans la classe.

Visibilité asymétrique RFC Doc

PHP < 8.4
class PhpVersion
{
private
string $version = '8.3';

public function
getVersion(): string
{
return
$this->version;
}

public function
increment(): void
{
[
$major, $minor] = explode('.', $this->version);
$minor++;
$this->version = "{$major}.{$minor}";
}
}
PHP 8.4
class PhpVersion
{
public private(
set) string $version = '8.4';

public function
increment(): void
{
[
$major, $minor] = explode('.', $this->version);
$minor++;
$this->version = "{$major}.{$minor}";
}
}
La portée d'écriture d'une propriété peut désormais être contrôlée indépendamment de sa portée de lecture, réduisant ainsi le besoin de méthodes getter redondantes pour exposer la valeur d'une propriété sans permettre sa modification depuis l'extérieur d'une classe.

L'attribut #[\Deprecated] RFC Doc

PHP < 8.4
class PhpVersion
{
/**
* @deprecated 8.3 use PhpVersion::getVersion() instead
*/
public function getPhpVersion(): string
{
return
$this->getVersion();
}

public function
getVersion(): string
{
return
'8.3';
}
}

$phpVersion = new PhpVersion();
// No indication that the method is deprecated.
echo $phpVersion->getPhpVersion();
PHP 8.4
class PhpVersion
{
#[
\Deprecated(
message: "use PhpVersion::getVersion() instead",
since: "8.4",
)]
public function
getPhpVersion(): string
{
return
$this->getVersion();
}

public function
getVersion(): string
{
return
'8.4';
}
}

$phpVersion = new PhpVersion();
// Deprecated: Method PhpVersion::getPhpVersion() is deprecated since 8.4, use PhpVersion::getVersion() instead
echo $phpVersion->getPhpVersion();
Le nouvel attribut #[\Deprecated] rend le mécanisme d'obsolescence existant de PHP disponible pour les fonctions, méthodes et constantes de classe définies par l'utilisateur.

Nouvelles fonctionnalités de l'extension ext-dom et prise en charge de HTML5. RFC RFC Doc

PHP < 8.4
$dom = new DOMDocument();
$dom->loadHTML(
<<<'HTML'
<main>
<article>PHP 8.4 is a feature-rich release!</article>
<article class="featured">PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.</article>
</main>
HTML,
LIBXML_NOERROR,
);

$xpath = new DOMXPath($dom);
$node = $xpath->query(".//main/article[not(following-sibling::*)]")[0];
$classes = explode(" ", $node->className); // Simplified
var_dump(in_array("featured", $classes)); // bool(true)
PHP 8.4
$dom = Dom\HTMLDocument::createFromString(
<<<HTML
<main>
<article>PHP 8.4 is a feature-rich release!</article>
<article class="featured">PHP 8.4 adds new DOM classes that are spec-compliant, keeping the old ones for compatibility.</article>
</main>
HTML,
LIBXML_NOERROR,
);

$node = $dom->querySelector('main > article:last-child');
var_dump($node->classList->contains("featured")); // bool(true)

Nouvelle API DOM offrant une prise en charge conforme aux standards pour l'analyse des documents HTML5, corrigeant plusieurs bogues de conformité de longue date dans le comportement des fonctionnalités DOM et ajoutant plusieurs fonctions pour faciliter la manipulation des documents.

La nouvelle API DOM est disponible dans l'espace de noms Dom. Les documents utilisant cette API peuvent être créés à l'aide des classes Dom\HTMLDocument et Dom\XMLDocument.

API objet pour BCMath RFC

PHP < 8.4
$num1 = '0.12345';
$num2 = 2;
$result = bcadd($num1, $num2, 5);

echo
$result; // '2.12345'
var_dump(bccomp($num1, $num2) > 0); // false
PHP 8.4
use BcMath\Number;

$num1 = new Number('0.12345');
$num2 = new Number('2');
$result = $num1 + $num2;

echo
$result; // '2.12345'
var_dump($num1 > $num2); // false

BCMath vous permet de travailler avec des nombres flottants de précision arbitraire en PHP. Avec cette version, vous pouvez bénéficier du style orienté objet et de la surcharge des opérateurs pour utiliser les nombres BCMath.

Cela signifie que vous pouvez désormais utiliser les opérateurs standard avec les objets BcMath\Number, ainsi que toutes les fonctions bc*.

Ces objets sont immuables et implémentent l'interface Stringable, afin d'être utilisés dans des chaînes de caractères tels que echo $num.

Nouvelles fonctions array_*() RFC

PHP < 8.4
$animal = null;
foreach ([
'dog', 'cat', 'cow', 'duck', 'goose'] as $value) {
if (
str_starts_with($value, 'c')) {
$animal = $value;
break;
}
}

var_dump($animal); // string(3) "cat"
PHP 8.4
$animal = array_find(
[
'dog', 'cat', 'cow', 'duck', 'goose'],
static fn (
string $value): bool => str_starts_with($value, 'c'),
);

var_dump($animal); // string(3) "cat"
Les nouvelles fonctions array_find(), array_find_key(), array_any() et array_all() sont désormais disponibles.

Parseurs SQL spécifiques au pilote PDO RFC

PHP < 8.4
$connection = new PDO(
'sqlite:foo.db',
$username,
$password,
);
// object(PDO)

$connection->sqliteCreateFunction(
'prepend_php',
static fn (
$string) => "PHP {$string}",
);

$connection->query('SELECT prepend_php(version) FROM php');
PHP 8.4
$connection = PDO::connect(
'sqlite:foo.db',
$username,
$password,
);
// object(Pdo\Sqlite)

$connection->createFunction(
'prepend_php',
static fn (
$string) => "PHP {$string}",
);
// Does not exist on a mismatching driver.

$connection->query('SELECT prepend_php(version) FROM php');
De nouvelles sous-classes Pdo\Dblib, Pdo\Firebird, Pdo\MySql, Pdo\Odbc, Pdo\Pgsql et Pdo\Sqlite de PDO sont désormais disponibles.

new MyClass()->method() sans parenthèses. RFC Doc

PHP < 8.4
class PhpVersion
{
public function
getVersion(): string
{
return
'PHP 8.3';
}
}

var_dump((new PhpVersion())->getVersion());
PHP 8.4
class PhpVersion
{
public function
getVersion(): string
{
return
'PHP 8.4';
}
}

var_dump(new PhpVersion()->getVersion());
Les propriétés et méthodes d'un objet nouvellement instancié peuvent désormais être accessibles sans entourer l'expression new entre parenthèses.

Nouvelles classes, interfaces et fonctions

  • Nouveaux objets à initialisation différée.
  • Nouvelle implémentation JIT basée sur le framework IR.
  • Nouvelle fonction request_parse_body().
  • Nouvelles fonctions bcceil(), bcdivmod(), bcfloor(), et bcround().
  • Nouvelle énumération RoundingMode pour round() avec 4 nouveaux modes d'arrondi TowardsZero, AwayFromZero, NegativeInfinity, et PositiveInfinity.
  • Nouvelle méthodes DateTime::createFromTimestamp(), DateTime::getMicrosecond(), DateTime::setMicrosecond(), DateTimeImmutable::createFromTimestamp(), DateTimeImmutable::getMicrosecond(), et DateTimeImmutable::setMicrosecond().
  • Nouvelles fonctions mb_trim(), mb_ltrim(), mb_rtrim(), mb_ucfirst(), et mb_lcfirst().
  • Nouvelles fonctions pcntl_getcpu(), pcntl_getcpuaffinity(), pcntl_getqos_class(), pcntl_setns(), et pcntl_waitid().
  • Nouvelles méthodes ReflectionClassConstant::isDeprecated(), ReflectionGenerator::isClosed(), et ReflectionProperty::isDynamic().
  • Nouvelles fonctions http_get_last_response_headers(), http_clear_last_response_headers(), et fpow().
  • Nouvelles méthodes XMLReader::fromStream(), XMLReader::fromUri(), XMLReader::fromString(), XMLWriter::toStream(), XMLWriter::toUri(), et XMLWriter::toMemory().
  • Nouvelle fonction grapheme_str_split().

Obsolescence et changements non rétrocompatibles

  • Les extensions IMAP, OCI8, PDO_OCI, et pspell ont été dissociées et transférées à PECL.
  • Les types de paramètres implicitement nullables sont désormais obsolètes.
  • L'utilisation de _ comme nom de classe est désormais obsolète.
  • L'élévation de zéro à la puissance d'un nombre négatif est désormais obsolète.
  • Le passage d'un mode invalide à round() déclenche une ValueError.
  • Les constantes de classe des extensions date, intl, pdo, reflection, spl, sqlite, xmlreader sont désormais typées.
  • La classe GMP est désormais final.
  • Les constantes MYSQLI_SET_CHARSET_DIR, MYSQLI_STMT_ATTR_PREFETCH_ROWS, MYSQLI_CURSOR_TYPE_FOR_UPDATE, MYSQLI_CURSOR_TYPE_SCROLLABLE, et MYSQLI_TYPE_INTERVAL ont été supprimées.
  • Les fonctions mysqli_ping(), mysqli_kill(), mysqli_refresh(), méthodes mysqli::ping(), mysqli::kill(), mysqli::refresh(), et constantes MYSQLI_REFRESH_* sont désormais obsolètes.
  • stream_bucket_make_writeable() et stream_bucket_new() renvoient désormais une instance de StreamBucket au lieu de stdClass.
  • Changement de comportement de la fonction exit().
  • La constante E_STRICT est désormais obsolète.
To Top