Un produit référencé disparaît sans que rien n’ait nettoyé les endroits où son identifiant continue d’être utilisé : c’est le scénario derrière la quasi-totalité des avertissements Attempt to read property "name" on null qui apparaissent dans les journaux d’une boutique WooCommerce en fonctionnement depuis plusieurs années. La fonction responsable, wc_get_product(), ne lève jamais d’exception quand l’identifiant demandé ne correspond à aucun produit existant : elle renvoie simplement false.
Le bug n’est donc jamais dans wc_get_product() elle-même, mais dans le code appelant qui suppose, à tort, qu’un objet produit valide est systématiquement renvoyé, et qui tente d’appeler une méthode ou de lire une propriété directement sur ce false.
Où ce motif se cache le plus souvent
- Des listes de souhaits ou de favoris qui stockent des identifiants de produit dans une table personnalisée ou une métadonnée utilisateur, jamais purgée à la suppression d’un produit.
- Des lignes de commande anciennes (
WC_Order_Item_Product) dont le produit lié a été supprimé après la commande, un cas parfaitement normal en soi. - Des scripts d’export ou de synchronisation ERP qui itèrent sur une liste d’identifiants figée, sans revérifier leur existence au moment du traitement.
Sécuriser chaque appel : le correctif immédiat
Le correctif de premier niveau consiste à toujours vérifier le retour de wc_get_product() avant de l’utiliser, ce qui élimine le warning immédiatement, sans modifier le comportement métier attendu :
$produit = wc_get_product( $product_id );
if ( ! $produit instanceof WC_Product ) {
// Le produit n'existe plus : traiter le cas explicitement
continue;
}
echo esc_html( $produit->get_name() );
Cette vérification devrait être systématique dans tout code personnalisé manipulant des identifiants de produit issus d’une source externe à la requête courante (métadonnée, table personnalisée, paramètre d’URL).

Le vrai problème : des références orphelines qui s’accumulent
Sécuriser l’appel évite le warning, mais ne résout pas la cause : des identifiants de produits supprimés continuent de s’accumuler dans des listes de souhaits, des historiques de navigation, ou des tables de recommandations personnalisées. Sans nettoyage périodique, ces références orphelines grossissent indéfiniment et ralentissent les requêtes qui les parcourent, en plus de générer le warning à chaque affichage.
Purger via le hook de suppression de produit
add_action( 'before_delete_post', function ( $post_id ) {
if ( get_post_type( $post_id ) !== 'product' ) {
return;
}
global $wpdb;
$wpdb->delete( $wpdb->prefix . 'boutique_favoris', array( 'product_id' => $post_id ) );
} );
Brancher la purge directement sur la suppression, via before_delete_post ou woocommerce_before_delete_product selon le contexte, évite d’avoir à exécuter des scripts de nettoyage périodiques a posteriori.
Cas des lignes de commande : ne jamais purger
Attention à ne pas appliquer la même logique de purge aux lignes de commandes existantes : un produit supprimé après avoir été vendu doit rester référencé dans l’historique de commande, pour des raisons comptables et de service client. Le correctif ici est uniquement défensif (vérifier avant d’afficher), jamais une suppression de la référence historique.
Sur nos projets, la règle est simple : on sécurise systématiquement l’affichage d’un produit potentiellement supprimé, mais on ne purge que les usages « vivants » — favoris, recommandations, paniers sauvegardés — jamais l’historique des commandes passées.
Détecter l’ampleur du problème avant de corriger au cas par cas
Avant de corriger chaque appel un par un, un script ponctuel permet de mesurer l’ampleur réelle du problème sur une boutique donnée, en comparant les identifiants référencés dans les tables personnalisées avec les identifiants de produits encore existants dans wp_posts.
En résumé
Le warning Attempt to read property on null sur wc_get_product() est un symptôme, pas la maladie : la maladie, ce sont des références orphelines jamais nettoyées après la suppression d’un produit. Sécuriser chaque appel élimine le message ; brancher une purge sur la suppression du produit élimine la cause.