Réponse anticipée

oxphp_finish_request() envoie immédiatement la réponse HTTP complète au client et laisse votre script PHP continuer de s'exécuter pour effectuer un travail en arrière-plan. C'est l'équivalent OxPHP de fastcgi_finish_request() dans PHP-FPM.

Fonctionnement

  1. Construire la réponse. Votre script définit les en-têtes, le code de statut et émet le corps de la réponse comme d'habitude.
  2. Terminer la requête. Appelez oxphp_finish_request(). OxPHP vide tous les tampons de sortie, marque la requête comme terminée et délivre la réponse HTTP complète au client.
  3. Exécuter le travail en arrière-plan. Le script poursuit son exécution pour effectuer un travail en arrière-plan, comme l'envoi d'e-mails, l'écriture d'entrées de cache ou l'envoi de webhooks.
  4. Toute sortie ultérieure est ignorée. Toute sortie produite après l'appel (echo, print, var_dump) est silencieusement ignorée.
  5. L'appel est idempotent. oxphp_finish_request() renvoie true au premier appel et false à tout appel ultérieur au sein de la même requête.

Cas d'usage

La réponse anticipée est utile chaque fois que vous souhaitez accuser réception d'une requête immédiatement tout en différant un travail non critique :

  • Envoi d'e-mails — renvoyez « accepted » immédiatement, envoyez l'e-mail en arrière-plan
  • Préchauffage du cache — répondez avec les données en cache, puis régénérez l'entrée de cache
  • Analytique et journalisation — accusez réception de la requête, puis écrivez des enregistrements analytiques détaillés
  • Envoi de webhooks — confirmez la réception à l'appelant, puis distribuez les livraisons de webhooks
  • Traitement d'images — renvoyez une URL immédiatement, puis traitez l'image en taille réelle

Exemples PHP

Utilisation de base

php
<?php header('Content-Type: application/json'); echo json_encode(['status' => 'accepted', 'id' => uniqid()]); // Send response now — client receives the full response at this point oxphp_finish_request(); // Background work runs here; client is no longer waiting file_put_contents('/tmp/audit.log', date('c') . " request processed\n", FILE_APPEND); send_notification_email($user);

Se prémunir contre le double appel

oxphp_finish_request() renvoie false au deuxième appel et aux suivants. Vérifiez la valeur de retour dans les applications riches en middleware où plusieurs couches pourraient appeler la fonction :

php
<?php function finish_and_cleanup(): void { if (!oxphp_finish_request()) { // Already finished — background work was already scheduled return; } // First call — safe to run cleanup flush_metrics_buffer(); close_external_connections(); }

Travail en arrière-plan conditionnel

php
<?php header('Content-Type: application/json'); $payload = json_decode(file_get_contents('php://input'), true); $result = handle_request($payload); echo json_encode($result); if ($result['needs_sync']) { oxphp_finish_request(); sync_to_external_service($result); } // No early finish if sync is not needed — script exits normally

Mode worker

En mode worker, le worker PHP reste occupé jusqu'à ce que l'intégralité du script (y compris tout le travail en arrière-plan) soit terminée. Le worker n'accepte pas de nouvelle requête tant que le callback n'a pas retourné.

php
<?php oxphp_worker(function () { $order = json_decode(file_get_contents('php://input'), true); $result = process_order($order); header('Content-Type: application/json'); echo json_encode(['order_id' => $result['id'], 'status' => 'accepted']); oxphp_finish_request(); // Worker is still occupied during this background work send_confirmation_email($result); update_inventory($result); notify_warehouse($result); // Worker becomes available after this point });
Note

Tenez compte du temps de traitement en arrière-plan lorsque vous dimensionnez votre pool de workers. Un worker qui passe 3 secondes en travail post-réponse après chaque requête traite en pratique moins de requêtes simultanées.

Dépannage

Le travail en arrière-plan ne se termine pas

Le paramètre max_execution_time de PHP continue de s'appliquer après l'appel de oxphp_finish_request(). Si le temps d'exécution total du script, travail en arrière-plan compris, dépasse la limite, la requête est annulée avec une erreur fatale Request cancelled (timeout).

Solution : Augmentez max_execution_time (dans php.ini ou via set_time_limit() depuis le script), ou déplacez les tâches d'arrière-plan longues vers une file de messages :

php
set_time_limit(300); oxphp_finish_request(); // ... long-running work ...

Pour un travail qui prend régulièrement plus de quelques secondes, publiez un message dans Redis, RabbitMQ ou une file similaire et laissez un consommateur dédié le traiter de manière asynchrone.

Les modifications de session sont perdues

Les données de session doivent être écrites avant d'appeler oxphp_finish_request(). Les modifications effectuées après l'appel sont ignorées.

Solution : Appelez session_write_close() avant oxphp_finish_request() :

php
<?php $_SESSION['last_seen'] = time(); session_write_close(); // Persist session before finishing oxphp_finish_request(); // Send response
Le corps de la réponse est vide après l'appel de oxphp_finish_request()

Si vous appelez oxphp_finish_request() avant toute sortie echo, le client reçoit un corps vide. Construisez et émettez d'abord la réponse, puis appelez la fonction.

Notes

  • oxphp_finish_request() renvoie true au premier appel et false aux appels suivants au sein de la même requête.
  • Toute sortie (echo, print, var_dump) après le premier appel est silencieusement ignorée.
  • En mode worker, le worker reste occupé jusqu'à ce que l'intégralité du callback soit terminée, y compris tout le code post-réponse.
  • Le délai d'expiration de la requête continue de s'appliquer au code d'arrière-plan qui s'exécute après oxphp_finish_request().
  • oxphp_finish_request() et oxphp_stream_flush() sont mutuellement exclusifs : appeler oxphp_finish_request() avant de démarrer un flux empêche le streaming, et l'appeler après oxphp_stream_flush() ferme le flux.

Voir aussi

  • Mode worker — les processus PHP persistants et la façon dont la réponse anticipée interagit avec la boucle de requêtes
  • Délais d'expiration — comment le délai d'expiration de la requête s'applique au travail en arrière-plan
  • Fonctions PHP — référence complète de oxphp_finish_request() et des autres fonctions intégrées