« Fires after WordPress has finished loading but before any headers are sent. » Cette phrase, tirée de la documentation officielle du hook init, décrit précisément ce que ce point d’accroche garantit, et surtout ce qu’il ne garantit pas : que toutes les extensions actives aient elles-mêmes terminé leur propre initialisation.
Un plugin de cache de fragments, développé pour accélérer un site à fort trafic, enregistrait son mécanisme de lecture du cache sur init, en tentant de vérifier si un autre plugin de personnalisation avait déjà enregistré ses propres filtres de contenu. Le problème : selon l’ordre de chargement des extensions, ce second plugin n’avait parfois pas encore eu l’occasion de s’enregistrer au moment où init se déclenchait pour le premier.
Ce que le hook init garantit réellement
init se déclenche après que WordPress a chargé le cœur, activé les plugins et le thème, et reconnu la requête entrante, mais avant l’envoi des en-têtes HTTP. Il reste néanmoins possible que certains plugins retardent volontairement une partie de leur propre initialisation à un hook ultérieur, pour des raisons qui leur sont propres, ce qui rend risqué tout code qui suppose que « tout » est prêt dès init.
Les hooks suivants et ce qu’ils apportent
wp_loadedse déclenche une fois que WordPress et tous les plugins actifs ont terminé de charger, un point plus fiable pour vérifier la présence de fonctionnalités enregistrées par d’autres extensions.parse_requestintervient après que WordPress a déterminé quelle requête est en cours de traitement, utile pour des décisions qui dépendent du type de page demandée.template_redirectse déclenche juste avant le choix du template à charger, le dernier moment raisonnable pour intervenir sur le flux d’affichage avant le rendu proprement dit.

Ce que le mauvais positionnement coûtait ici
Le plugin de cache de fragments, faute de trouver les filtres attendus lors de son passage sur init, retombait systématiquement sur un chemin de secours plus coûteux, recalculant certains fragments qui auraient normalement dû être servis directement depuis le cache. Ce comportement dégradé passait inaperçu en apparence, puisque le site continuait de fonctionner correctement, seulement plus lentement qu’attendu sur certaines pages.
Le correctif appliqué
add_action('wp_loaded', function () {
if (function_exists('personnalisation_filtres_actifs')) {
add_filter('cache_fragment_contexte', 'lire_contexte_personnalisation');
}
});
Déplacer l’enregistrement du filtre de init vers wp_loaded a suffi à garantir que la fonction de l’autre plugin, quel que soit son ordre de chargement relatif, soit systématiquement disponible au moment de la vérification.
Une confusion fréquente à corriger
Beaucoup de développeurs choisissent init par habitude, parce que c’est le premier hook mentionné dans la plupart des tutoriels d’introduction, sans se demander si leur traitement dépend réellement d’un état garanti seulement plus tard dans le cycle. La question à se poser avant de choisir un hook n’est pas « est-ce que ça marche en test », mais « quelle garantie précise ce hook m’offre-t-il, documentée noir sur blanc ».
Un test simple pour vérifier une hypothèse d’ordre
Avant de choisir un hook pour un traitement qui dépend d’une autre extension, il est utile d’ajouter temporairement une trace de journalisation dans les deux hooks candidats, afin d’observer concrètement l’ordre réel d’exécution sur l’environnement de production, pas seulement sur l’environnement de développement où l’ensemble des plugins actifs peut différer.
add_action('init', function () {
error_log('init : personnalisation_filtres_actifs existe = '
. (function_exists('personnalisation_filtres_actifs') ? 'oui' : 'non'));
}, 999);
add_action('wp_loaded', function () {
error_log('wp_loaded : personnalisation_filtres_actifs existe = '
. (function_exists('personnalisation_filtres_actifs') ? 'oui' : 'non'));
});
Sur ce projet, cette trace a confirmé sans ambiguïté que la fonction attendue n’existait pas encore au moment de init avec une priorité tardive de 999, mais qu’elle existait bien systématiquement dès wp_loaded, validant le choix du correctif retenu avant même de le déployer en production.
En résumé
Le choix d’un hook de chargement ne doit jamais reposer sur l’ordre observé empiriquement sur un site donné, cet ordre pouvant changer avec l’activation d’une nouvelle extension. Il doit reposer sur la garantie documentée de ce hook : ce qui est certainement chargé avant lui, et ce qui ne l’est pas forcément.