« Notice: Undefined property: WP_User::$ID » sur un code qui semble pourtant correct : wp_get_current_user()->ID, exactement comme dans la documentation. Le symptôme n’apparaît pas à chaque chargement de page, ce qui rend son diagnostic plus long que nécessaire — il dépend en réalité de l’endroit précis où cet appel est placé dans le cycle de chargement de WordPress, pas d’une erreur de syntaxe.
Symptôme
Un appel à wp_get_current_user() retourne parfois un objet WP_User vide, avec un ID égal à zéro, alors qu’un utilisateur est bel et bien connecté. Le problème est intermittent en apparence : il se manifeste selon l’endroit du code où l’appel est effectué, pas selon une condition liée à l’utilisateur lui-même.
Diagnostic
WordPress charge les informations de l’utilisateur courant à un moment précis de son cycle de démarrage, après l’exécution des extensions les plus précoces mais avant le rendu du contenu. Un appel à wp_get_current_user() effectué trop tôt — directement dans un fichier chargé au niveau global d’une extension, avant le hook plugins_loaded, ou même pendant plugins_loaded dans certains cas limites — intervient avant que cette information soit disponible.

// Dans le fichier principal d'une extension, en dehors de tout hook :
$utilisateur = wp_get_current_user();
echo $utilisateur->ID; // 0, même si un utilisateur est connecté
Ce code s’exécute au moment où PHP charge le fichier, bien avant que WordPress ait fini d’initialiser l’objet représentant l’utilisateur courant à partir des cookies d’authentification.
Correctif
add_action( 'init', 'ma_fonction_qui_lit_utilisateur' );
function ma_fonction_qui_lit_utilisateur() {
$utilisateur = wp_get_current_user();
if ( 0 === $utilisateur->ID ) {
// Visiteur non connecté, cas normal à gérer séparément.
return;
}
echo $utilisateur->ID;
}
Le hook init se déclenche après que WordPress a fini de résoudre l’utilisateur courant à partir de la session active, ce qui en fait le premier point d’entrée fiable pour ce genre d’appel. Un appel plus tardif, sur wp ou template_redirect, fonctionne également, mais init suffit pour la grande majorité des besoins.
Prévention
- Aucun appel à
wp_get_current_user(),is_user_logged_in()oucurrent_user_can()ne devrait figurer au niveau global d’un fichier PHP, hors de tout hook. - Le hook
plugins_loadedreste trop précoce pour ce besoin spécifique : il concerne le chargement des extensions elles-mêmes, pas la résolution de l’utilisateur courant. - Une extension qui doit réagir différemment selon le rôle de l’utilisateur dès le chargement le plus précoce possible devrait plutôt reporter cette logique à l’intérieur du hook
init, quitte à retarder légèrement son exécution.
Un test rapide pour confirmer le diagnostic
Ajouter temporairement un error_log( current_action() ) juste avant l’appel suspect permet de vérifier immédiatement à quel stade du chargement il se situe, et de comparer avec le hook init pour confirmer que le problème vient bien d’un appel trop précoce plutôt que d’une autre cause.
Un repère simple à garder en tête : tant qu’un développeur n’a pas explicitement accroché son code à un hook, il ne sait pas réellement à quel moment du cycle de chargement il s’exécute. C’est particulièrement vrai pour tout ce qui touche à l’utilisateur courant.
En résumé
Un objet utilisateur vide alors qu’une session est active pointe presque toujours vers un appel effectué trop tôt dans le cycle de chargement de WordPress. Déplacer cet appel à l’intérieur du hook init résout ce symptôme dans l’immense majorité des cas, sans qu’aucune autre modification du code ne soit nécessaire.