PHP 8.5 dans Laravel : ce qui mérite sa place, ce qu'il faut vérifier
PHP 8.5 est sorti le 20 novembre 2025, et une annonce de version liste des fonctionnalités sans vous dire lesquelles ont leur place dans un code Laravel. Certaines changent vraiment la façon dont le code applicatif se lit. D'autres règlent un problème que Laravel a réglé il y a des années avec un helper. Et quelques dépréciations valent une recherche avant de faire passer un projet à la nouvelle version. Voici ce tri, fonctionnalité par fonctionnalité.
Celles qui méritent une place dans le code applicatif
array_first() et array_last(). Elles renvoient la première ou la dernière valeur d'un tableau, ou null s'il est vide, donc elles se combinent avec ??. Pour obtenir le dernier événement, on écrivait jusqu'ici $events === [] ? null : $events[array_key_last($events)]. Dans une collection vous avez déjà first() et last(), et Arr::first() existe, mais beaucoup de code Laravel manipule des tableaux simples : valeurs de config, JSON décodé, données de requête. C'est là que ces deux fonctions servent.
L'opérateur pipe. |> fait passer une valeur dans une suite de callables, de gauche à droite, sans variable temporaire. L'exemple de php.net transforme un titre en slug :
$slug = $title
|> trim(...)
|> (fn($s) => str_replace(' ', '-', $s))
|> (fn($s) => str_replace('.', '', $s))
|> strtolower(...);
// ' PHP 8.5 Released ' becomes 'php-85-released'
Soyons honnêtes : dans une app Laravel, vous écririez Str::slug($title), et les chaînes fluides comme la classe Pipeline couvrent déjà beaucoup d'enchaînements de ce genre. Le pipe trouve sa place là où aucun helper n'existe, pour une suite de petites fonctions à vous que vous imbriqueriez sinon, ou que vous étaleriez sur quatre variables jetables.
clone with. C'est celle qui compte le plus pour du code qui suit la règle fixée par les propres standards de code de ce site : des objets valeur plutôt que des tableaux fourre-tout. Une classe readonly est le bon endroit pour une valeur qui traverse les couches, mais jusqu'à 8.5, chaque méthode « with » obligeait à recopier chaque propriété à la main dans un appel new self(...), ou à jongler avec get_object_vars(). Désormais, clone accepte les propriétés à remplacer :
final readonly class Color
{
public function __construct(
public int $red, public int $green, public int $blue,
public float $alpha = 1.0,
) {}
public function withAlpha(float $alpha): self
{
return clone($this, ['alpha' => $alpha]);
}
}
#[\NoDiscard]. Posé sur une fonction, il fait émettre un avertissement par PHP quand la valeur de retour est ignorée ; un cast (void) marque un appel dont on ignore volontairement le résultat. Cela va très bien aux objets résultat : une méthode qui renvoie un succès ou un échec au lieu de lever une exception est exactement celle qu'on appelle en oubliant de vérifier.
L'extension URI. Elle est intégrée, toujours disponible, et analyse les URL selon la RFC 3986 ou le standard URL du WHATWG, en s'appuyant sur uriparser et Lexbor. (new Uri\Rfc3986\Uri($url))->getHost() remplace parse_url($url)['host'], et vous obtenez un parseur qui suit un standard nommé au lieu des règles maison de parse_url(). Partout où vous vérifiez un hôte avant une redirection, ou comparez l'URL d'un webhook à une liste autorisée, le changement en vaut la peine.
Le reste de la liste, les handles cURL partagés persistants, les closures dans les expressions constantes, les backtraces sur les erreurs fatales comme un timeout, les attributs sur les constantes, est utile mais a moins de chances de changer le code courant des contrôleurs et des services.
Ce qu'il faut vérifier avant de migrer
Rien de tout cela n'est une raison d'attendre ; c'est une liste de choses à chercher. Utiliser null comme clé de tableau, ou dans array_key_exists(), est déprécié, et dans du code Laravel cela se cache souvent dans une recherche dont la clé peut être nulle. Les casts non canoniques (integer), (boolean), (double) et (binary) sont dépréciés, tout comme l'opérateur backtick et un case terminé par un point-virgule. __sleep() et __wakeup() sont dépréciés en douceur au profit de __serialize() et __unserialize() : vérifiez vos propres classes sérialisées dans les payloads de file d'attente ou dans le cache. PHP avertit désormais quand un float non représentable est converti en int, quand NAN est converti, et quand on déstructure quelque chose qui n'est ni un tableau ni null. Côté serveur, le réglage ini disable_classes a disparu.
Ce site est un bon exemple de la situation de la plupart des projets. Il tourne sous Laravel 13.35.0, et son composer.json exige PHP ^8.4.1. PHP 8.5 satisfait cette contrainte, mais 8.4 aussi, donc aucune des syntaxes 8.5 ci-dessus ne peut entrer dans ce code tant que la contrainte n'est pas relevée.
Un premier pas concret pour un projet Laravel : cherchez dans le code __sleep, __wakeup, (integer), (boolean) et les backticks, puis lancez les tests sur 8.5. Ensuite, la première classe readonly que vous touchez est un bon endroit pour essayer clone with. Source : php.net, annonce de la version PHP 8.5.
Ce que disent les lecteurs