$template?->origin?->source?->label — quatre maillons, un seul point d’interrogation avant chaque flèche, et la certitude qu’aucun d’entre eux ne provoquera d’erreur fatale si l’un des objets intermédiaires n’existe pas. C’est exactement le genre de situation qui se présente en manipulant un objet de gabarit récupéré via get_block_template(), dont certaines propriétés imbriquées ne sont pas toujours renseignées selon l’origine du gabarit (fichier de thème, enregistrement en base, ou gabarit hérité d’un thème parent).
Avant PHP 8, atteindre une propriété enfouie dans plusieurs niveaux d’objets potentiellement absents imposait une cascade de vérifications, chacune protégeant la suivante :
$label = null;
if ( isset( $template ) && isset( $template->origin ) ) {
if ( isset( $template->origin->source ) ) {
$label = $template->origin->source->label ?? null;
}
}
Ce code fonctionne, mais il grandit vite : chaque niveau supplémentaire de propriété optionnelle ajoute un niveau d’imbrication, jusqu’à rendre la logique métier réelle difficile à repérer au milieu des vérifications défensives.
Ce que fait l’opérateur nullsafe
Introduit avec PHP 8.0, l’opérateur ?-> remplace la flèche d’accès habituelle. Dès qu’il rencontre une valeur null à gauche, il court-circuite immédiatement toute la chaîne et retourne null, sans tenter d’accéder à la propriété suivante et sans déclencher d’erreur ou d’avertissement :

$label = $template?->origin?->source?->label;
Cette seule ligne reproduit exactement le comportement de la cascade de isset() précédente, avec un point important : si $template lui-même vaut null, la chaîne entière est court-circuitée dès le premier maillon, sans qu’il soit nécessaire de le vérifier séparément en amont.
Application concrète sur un objet de gabarit
L’objet retourné par get_block_template() est une instance de WP_Block_Template. Certaines de ses propriétés, comme origin, peuvent rester vides selon que le gabarit provient d’un fichier de thème, d’un enregistrement personnalisé en base, ou d’un thème parent hérité. Une fonction qui affiche une information conditionnelle basée sur cette origine profite directement de cette syntaxe :
function afficher_origine_gabarit( $template_id ) {
$template = get_block_template( $template_id );
$origine = $template?->source ?? 'inconnue';
printf(
'<p>Origine du gabarit : %s</p>',
esc_html( $origine )
);
}
La combinaison avec l’opérateur de coalescence ?? reste utile ici : le nullsafe gère l’absence d’un objet intermédiaire, la coalescence fournit une valeur de repli quand le résultat final est null.
Ce que l’opérateur nullsafe ne fait pas
Il protège contre l’absence d’un objet, pas contre un type inattendu. Si une propriété contient, par erreur, une chaîne de caractères là où un objet était attendu, l’opérateur nullsafe ne rattrapera rien : PHP lèvera une erreur au moment d’essayer d’accéder à une propriété sur une valeur qui n’est ni un objet ni null. Pour ce cas, une vérification de type explicite reste nécessaire, par exemple avec is_object() avant l’accès si la source de la donnée n’est pas totalement fiable.
- L’opérateur nullsafe convient pour des propriétés dont l’absence est un état normal et attendu.
- Il ne convient pas comme filet de sécurité générique face à des données de provenance incertaine.
- Il s’utilise aussi bien sur des appels de méthode (
$objet?->methode()) que sur des accès de propriété.
Un piège à éviter : l’affectation
L’opérateur nullsafe ne fonctionne qu’en lecture. Tenter de l’utiliser du côté gauche d’une affectation, comme dans $template?->origin = 'theme', ne produit pas le comportement attendu et doit être évité : pour une affectation conditionnelle, une vérification classique reste nécessaire.
Sur les objets de gabarit qu’on manipule régulièrement, le repère qu’on garde en tête : l’opérateur nullsafe simplifie la lecture d’une chaîne de propriétés optionnelles, il ne dispense jamais de valider le type d’une donnée dont la provenance reste incertaine.
En résumé
Pour lire une propriété optionnelle imbriquée sur plusieurs niveaux, l’opérateur nullsafe de PHP 8 remplace avantageusement une cascade de vérifications répétées, en une seule ligne lisible. Il reste toutefois un outil de confort de lecture, pas un mécanisme de validation : ces deux besoins restent distincts, même si la syntaxe concise pousse parfois à les confondre.