Contrairement à un scan lancé manuellement une fois par mois depuis un tableau de bord, un scan automatisé qui vérifie en continu l’intégrité des fichiers, la présence de signatures malveillantes connues ou la cohérence des permissions d’un site pose un problème d’architecture dès qu’il s’exécute pendant une requête visiteur : chaque vérification lourde — hachage de fichiers, comparaison à une base de signatures, appel à une API externe de réputation — ajoute une latence directement perceptible.
Le réflexe naturel consiste à accrocher ces vérifications à un hook comme init ou wp_loaded, avec une condition de fréquence stockée en option. Ce choix fonctionne à petite échelle, mais dès que le site reçoit un trafic soutenu, la vérification se déclenche de façon imprévisible, potentiellement plusieurs fois en parallèle sur des requêtes concurrentes, et son temps d’exécution s’ajoute directement au temps de réponse perçu par le visiteur qui a eu la malchance de déclencher le scan.
Le principe : séparer déclenchement et exécution
L’architecture qui évite ce problème repose sur une file de traitement : le déclenchement d’un scan est planifié indépendamment du trafic, et son exécution effective a lieu dans un contexte détaché de toute requête HTTP visiteur. Deux briques du cœur WordPress permettent de construire cela sans dépendance externe :
wp_schedule_event()pour la planification périodique- Le hook cron personnalisé associé, exécuté par le pseudo-cron de WordPress ou par une tâche cron système appelant
wp-cron.phpavecDISABLE_WP_CRONactivé
Construire la file : un exemple minimal
La planification s’enregistre à l’activation :
register_activation_hook( __FILE__, function () {
if ( ! wp_next_scheduled( 'scanmodere_verifier_fichiers' ) ) {
wp_schedule_event( time(), 'hourly', 'scanmodere_verifier_fichiers' );
}
} );
add_action( 'scanmodere_verifier_fichiers', 'scanmodere_executer_verification' );

Le point important n’est pas seulement la planification, mais le découpage du travail lui-même : un scan complet d’un site avec plusieurs milliers de fichiers ne doit jamais s’exécuter d’un seul bloc dans une seule invocation cron, sous peine de dépasser le temps d’exécution maximal PHP configuré sur l’hébergement.
Découper le travail en lots
function scanmodere_executer_verification() {
$lot_precedent = (int) get_option( 'scanmodere_curseur', 0 );
$fichiers = scanmodere_lister_fichiers();
$lot = array_slice( $fichiers, $lot_precedent, 200 );
foreach ( $lot as $fichier ) {
scanmodere_verifier_signature( $fichier );
}
$nouveau_curseur = $lot_precedent + count( $lot );
if ( $nouveau_curseur >= count( $fichiers ) ) {
$nouveau_curseur = 0; // On repart du début au prochain passage.
}
update_option( 'scanmodere_curseur', $nouveau_curseur, false );
}
Cette approche par curseur, stocké en option sans autoload, permet de répartir la charge sur plusieurs exécutions cron successives plutôt que de tout traiter en une fois. Sur un site de taille moyenne, un lot de 200 fichiers par heure reste largement absorbable sans impact visible.
Alerter sans bloquer
Quand une vérification détecte une anomalie, l’envoi de la notification (email, webhook vers un outil de supervision) doit lui aussi rester détaché de l’exécution principale du scan, pour éviter qu’un service de notification lent ne ralentisse le traitement du lot suivant. Utiliser wp_schedule_single_event() pour planifier l’envoi de l’alerte dans les secondes suivantes, plutôt que de l’exécuter en ligne, garde le scan rapide et prévisible.
Pourquoi ne pas simplement utiliser Action Scheduler
La bibliothèque Action Scheduler, intégrée notamment à WooCommerce, propose une file de tâches plus robuste que le cron natif : reprise après échec, visibilité sur les tâches en attente, exécution en arrière-plan indépendante du trafic HTTP. Pour un projet qui l’utilise déjà, il est presque toujours préférable de s’appuyer dessus plutôt que de réinventer une file maison avec de simples options WordPress, comme illustré ci-dessus par souci de généralité.
Limiter l’impact même en cas de pic de trafic
Le pseudo-cron de WordPress se déclenche par défaut à l’occasion d’une visite, ce qui signifie qu’un pic de trafic peut multiplier les tentatives de déclenchement d’un même événement planifié. Définir DISABLE_WP_CRON à true dans wp-config.php et déclencher wp-cron.php via une tâche cron système à intervalle fixe élimine cette dépendance au trafic, et garantit une fréquence d’exécution stable quelle que soit l’affluence du site.
En résumé
Un scan de sécurité qui s’exécute dans le cycle de vie d’une requête visiteur finit toujours par se voir, tôt ou tard, dans les temps de réponse. Découpler le déclenchement de l’exécution via une file de traitement, répartir le travail en lots via un curseur, et s’appuyer sur un cron système plutôt que sur le pseudo-cron déclenché par le trafic, permet de faire tourner ces vérifications en continu sans jamais impacter l’expérience des visiteurs.