PHP 8.3 est sorti le 23 novembre 2023 et, plutôt que de réinventer le langage, il apporte des dizaines d'améliorations concrètes qui fluidifient le quotidien du développeur. Parmi les points forts : les typed class constants pour une meilleure sûreté de typage, la fonction json_validate() pour valider du JSON sans surcoût, l'attribut #[\Override] qui détecte tôt les erreurs d'héritage, et quelques gains de performance discrets. Dans cet article, nous parcourons les nouveautés qui vous serviront vraiment, avec du code réel et exécutable.
Constantes de classe typées : enfin un typage sûr
Pendant des années, PHP a refusé les déclarations de type sur les constantes. Une sous-classe pouvait redéfinir une constante héritée avec le mauvais type, et l'erreur n'apparaissait qu'à l'exécution — au pire, en production. PHP 8.3 permet de déclarer un type sur les constantes de classe, d'interface, de trait et d'enum.
interface Colore
{
const string DEFAUT = 'bleu';
}
class Carte implements Colore
{
// Erreur : type incompatible (string attendu, int fourni)
// const string DEFAUT = 0xFF;
const string DEFAUT = 'rouge';
}
Détail essentiel : la constante de l'enfant doit rester compatible avec le type défini dans le parent. Si une constante est typée int, une classe héritière ne peut pas la transformer en string. Sur de grandes bases de code, cela rend les contrats bien plus fiables.
json_validate() : vérifier la validité sans gaspiller de mémoire
Auparavant, la seule méthode pratique pour savoir si une chaîne était du JSON valide consistait à appeler json_decode() et à inspecter les erreurs. Mais cela construisait toute une structure de données PHP en mémoire, même quand on ne voulait qu'une réponse oui/non. json_validate() corrige précisément ce gaspillage : elle analyse sans rien construire et indique simplement si l'entrée est valide.
$brut = '{"nom":"Aslain","langues":["tr","en","de"]}';
if (json_validate($brut)) {
$data = json_decode($brut, true);
// traiter en toute sécurité
} else {
// corps mal formé — renvoyer 400
}
C'est surtout précieux lorsque vous voulez seulement filtrer des corps de webhook, des requêtes API ou de gros payloads fournis par l'utilisateur selon « est-ce valide ? ». Quand vous avez réellement besoin du contenu, vous appelez toujours json_decode().
L'attribut #[\Override] : faire vérifier vos redéfinitions par le moteur
Vous croyez redéfinir une méthode du parent, mais une petite faute de frappe se glisse dans le nom ; au lieu de redéfinir, vous déclarez une toute nouvelle méthode, et le bug disparaît silencieusement. L'attribut #[\Override] de PHP 8.3 élimine toute cette catégorie d'erreurs : vous déclarez qu'une méthode provient bien d'un type parent, et si ce n'est pas le cas, PHP lève une erreur fatale.
class FileBase
{
public function traiter(): void {}
}
class FileRedis extends FileBase
{
#[\Override]
public function traiter(): void
{
// redéfinition garantie
}
}
Cet attribut est inestimable dans le code qui implémente des interfaces ou comporte de longues chaînes d'héritage. Dès qu'un parent renomme une méthode, chaque sous-classe portant #[\Override] proteste immédiatement, évitant une régression silencieuse avant qu'elle ne survienne.
Accès dynamique aux constantes et nouveaux utilitaires de chaînes
Avant PHP 8.3, garder le nom d'une constante dans une variable et y accéder dynamiquement imposait des détours comme constant(). Désormais, on y accède directement avec la syntaxe à accolades :
class Statut
{
const ACTIF = 'actif';
const INACTIF = 'inactif';
}
$champ = 'ACTIF';
echo Statut::{$champ}; // "actif"
Deux petites fonctions pratiques sont aussi arrivées pour la génération de chaînes : str_increment() et str_decrement(). Elles incrémentent et décrémentent des chaînes alphanumériques de façon logique, comme le ferait une plaque d'immatriculation ou un numéro de série :
echo str_increment('Az'); // "Ba"
echo str_increment('A9'); // "B0"
echo str_decrement('B0'); // "A9"
Clonage readonly et ajouts à Randomizer
Les propriétés readonly introduites en PHP 8.2 étaient puissantes mais avaient une limite : impossible de modifier leur valeur lors du clonage. PHP 8.3 lève cette restriction — vous pouvez maintenant réinitialiser une propriété readonly à l'intérieur de __clone(). Cela rend bien plus propre la création de copies « with » d'objets immuables.
final class Argent
{
public function __construct(
public readonly int $centimes,
) {}
public function __clone(): void
{
// réaffectation autorisée pendant le clonage
}
}
Côté aléatoire, la classe Random\Randomizer a gagné de nouvelles méthodes : getFloat(), nextFloat() et getBytesFromString(). Elles offrent des solutions en une ligne et sans biais pour générer une chaîne aléatoire à partir d'un alphabet donné (mots de passe, tokens ou codes promo) ou un float dans une plage contrôlée.
Performance et autres petites touches
PHP 8.3 ne promet pas un bond de vitesse vertigineux, mais les améliorations au niveau du moteur et du JIT apportent des gains stables et mesurables sur les charges web classiques. Quelques autres points méritent attention :
- Protection contre le débordement de pile :
zend.max_allowed_stack_sizepermet d'arrêter une récursion profonde ou infinie par une erreur propre plutôt qu'un segfault. - Exceptions Date/Time plus précises : les classes de date lèvent désormais des exceptions spécifiques comme
DateMalformedStringExceptionau lieu d'uneExceptiongénérique. DateTime::createFromTimestamp(): une nouvelle méthode statique pour construire un objet date directement et lisiblement à partir d'un timestamp.- Classes anonymes readonly : vous pouvez maintenant écrire
new readonly class { ... }.
Conseil pratique : si vous démarrez un nouveau projet, choisissez directement PHP 8.3 (ou plus récent). Sur un projet Laravel ou PHP existant, augmentez d'abord la contrainte de version dans composer.json, puis lancez votre suite de tests ; comme 8.3 est largement rétrocompatible, la migration est généralement indolore.
Questions fréquentes
Passer de PHP 8.2 à 8.3 est-il difficile ?
Dans la plupart des cas, non. PHP 8.3 introduit peu de ruptures ; les principales nouveautés sont additives. Le plus sûr reste néanmoins de lancer vos tests automatisés et de confirmer la prise en charge de 8.3 par vos dépendances avant la mise en production.
json_validate() est-il toujours plus rapide que json_decode() ?
Son vrai atout est la mémoire : json_validate() ne construit aucune structure de données PHP, il consomme donc moins de mémoire sur de gros payloads. Mais si vous avez réellement besoin des données, vous appelez quand même json_decode() ensuite — auquel cas décoder une seule fois en vérifiant les erreurs peut être plus pertinent que deux appels.
Les constantes typées cassent-elles les constantes existantes ?
Non. La déclaration de type est facultative ; vos constantes non typées actuelles continuent de fonctionner exactement comme avant. Vous pouvez ajouter les types progressivement, là où vous voulez cette garantie supplémentaire.
Vous souhaitez moderniser votre stack PHP ? Travaillons ensemble sur une mise à niveau Laravel ou PHP pur vers 8.3, avec sûreté de typage et revue de performance. Contactez-moi et discutons de votre projet.