ignore_user_abort()
Découvrez la fonction PHP ignore_user_abort() : fonctionnement, signature, valeur de retour et exemples de tâches en arrière-plan.
La fonction PHP ignore_user_abort() contrôle si un script continue de s'exécuter après la déconnexion du client (le navigateur de l'utilisateur). Cette page explique ce que fait la fonction, sa signature et sa valeur de retour, comment elle fonctionne avec connection_aborted(), les pièges courants et un exemple complet de tâche en arrière-plan.
Ce que fait ignore_user_abort()
Lorsqu'un utilisateur ferme l'onglet du navigateur, appuie sur Stop ou navigue ailleurs, la connexion au serveur est coupée. Par défaut, PHP n'arrête pas immédiatement le script — il ne détecte la connexion perdue que la prochaine fois qu'il tente d'envoyer une sortie au navigateur, moment auquel il met fin au script. ignore_user_abort() modifie ce comportement : lorsqu'il est activé, PHP continue d'exécuter le script jusqu'à la fin même si personne n'écoute plus.
Cela est important pour les opérations qui ne doivent pas rester à moitié terminées — écriture dans une base de données, traitement d'un paiement, envoi d'un e-mail ou génération d'un rapport. Si l'utilisateur se déconnecte en cours de route, il est généralement préférable que le travail se termine plutôt que de laisser le système dans un état incohérent.
Un « abandon client » est un événement au niveau du transport : PHP ne le détecte que lorsqu'il tente d'écrire dans une connexion déjà fermée. C'est pourquoi le moment de détection semble indirect — voir Pourquoi l'abandon est détecté tardivement ci-dessous.
Syntaxe
ignore_user_abort(?bool $enable = null): int$enable— passeztruepour ignorer les déconnexions client, oufalsepour restaurer le comportement par défaut (arrêt sur déconnexion). Si vous omettez l'argument, le réglage actuel est conservé et simplement retourné.- Valeur de retour — le réglage précédent sous forme d'entier (
1= ignorait les abandons,0= ne les ignorait pas). Cela vous permet de sauvegarder et de restaurer l'état.
<?php
$previous = ignore_user_abort(true); // turn it on, remember old value
// ... critical work ...
ignore_user_abort($previous); // restore whatever it was beforeLe même réglage peut être configuré globalement dans php.ini avec la directive ignore_user_abort ; l'appel de la fonction le remplace pour la requête en cours.
Utilisation de base
Appelez la fonction une fois près du début du travail que vous souhaitez protéger :
<?php
// Keep running even if the user disconnects.
ignore_user_abort(true);
// Critical code that must not be interrupted.
saveOrderToDatabase();
chargePayment();
sendConfirmationEmail();
// Optional: go back to the default behaviour.
ignore_user_abort(false);Notez que ignore_user_abort() maintient le script en vie, mais ne supprime pas la limite max_execution_time de PHP. Une tâche longue peut toujours être arrêtée par la limite de temps, combinez donc cette fonction avec set_time_limit() si nécessaire.
Détecter l'abandon avec connection_aborted()
Ignorer un abandon ne signifie pas que vous ne pouvez pas y réagir. La fonction connection_aborted() retourne 1 une fois que le client s'est déconnecté et 0 sinon, vous pouvez donc la vérifier dans une boucle et décider de continuer, de nettoyer et de quitter.
Une subtilité : PHP ne met à jour le statut de connexion que lorsqu'il tente d'envoyer une sortie et que le tampon est vidé. Pour détecter un abandon en cours de boucle, vous faites généralement un echo de quelque chose et le flush(), ce qui force PHP à remarquer le socket fermé.
<?php
ignore_user_abort(true);
for ($i = 0; $i < 10; $i++) {
// Push some output so PHP checks the connection state.
echo "Step $i\n";
flush();
// connection_aborted() returns 1 after the client disconnects.
if (connection_aborted()) {
// The user left — stop early and clean up if we want to.
break;
}
doExpensiveStep($i);
}
ignore_user_abort(false);Ici connection_aborted() laisse le script décider lui-même : il peut terminer silencieusement, enregistrer que l'utilisateur est parti, ou sortir de la boucle prématurément. En relation : connection_status() signale les trois états (normal, abandonné, expiré) sous forme de masque de bits.
Un exemple pratique de tâche en arrière-plan
Un modèle courant consiste à envoyer la réponse, fermer la connexion pour que le navigateur arrête d'attendre, puis continuer le travail lourd en arrière-plan. ignore_user_abort(true) est ce qui rend la partie « continuer » fonctionnelle.
<?php
// 1. Keep running after the browser is released.
ignore_user_abort(true);
set_time_limit(0); // no execution-time cap for the background work
// 2. Send the response and flush the output buffers.
ob_start();
echo "Thanks! Your request is being processed.";
$size = ob_get_length();
header("Content-Length: $size");
header("Connection: close");
ob_end_flush();
flush();
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request(); // PHP-FPM: detach from the client now
}
// 3. The user's browser is already done. This runs regardless.
processLargeReport();Le navigateur reçoit une réponse rapide et arrête de tourner, tandis que le serveur termine le travail lent. Sans ignore_user_abort(true), ce travail en arrière-plan serait arrêté dès que PHP remarquerait la connexion fermée.
Pourquoi l'abandon est détecté tardivement
PHP met la sortie en tampon. Tant que ce tampon n'est pas vidé vers le client, PHP n'a aucune raison de toucher le socket et ne sait donc jamais qu'il est fermé. C'est pourquoi les scripts qui ne produisent aucune sortie (ou dont la sortie reste en tampon) peuvent s'exécuter jusqu'à la fin après une déconnexion sans jamais signaler connection_aborted() === 1. Si vous avez besoin d'une détection d'abandon rapide, émettez un petit signal de vie et videz-le avec flush() périodiquement, comme dans la boucle ci-dessus. Les assistants de mise en tampon de sortie comme ob_flush() et ob_end_flush() vous donnent un contrôle plus fin sur le moment où les données quittent le tampon.
Pièges courants
- Elle ne remplace pas la limite de temps. Utilisez
set_time_limit(0)(ou une valeur généreuse) en complément pour les tâches longues. - La détection nécessite une sortie + un flush.
connection_aborted()ne passera pas à1seule si votre script n'écrit jamais vers le client. - Un script incontrôlable est plus difficile à arrêter. Avec les abandons ignorés, une boucle infinie boguée continue de consommer des ressources car l'utilisateur ne peut plus l'annuler. Associez toujours cette fonction à des limites raisonnables.
- Les scripts CLI ne sont pas affectés. Il n'y a pas de connexion client en ligne de commande, donc la fonction est sans effet là — utilisez-la dans des contextes web (requête).
Conclusion
ignore_user_abort() maintient un script PHP en cours d'exécution après la déconnexion du client, ce qui est essentiel pour terminer en toute sécurité des travaux critiques ou en arrière-plan. Combinez-la avec connection_aborted() pour détecter les déconnexions, flush() pour forcer cette détection, et set_time_limit() pour éviter d'être interrompu en plein milieu d'une tâche, et vous disposez d'un modèle fiable pour les travaux qui ne doivent pas rester inachevés.