W3docs

ignore_user_abort()

Aprende a usar la función ignore_user_abort() de PHP para controlar si un script continúa ejecutándose tras la desconexión del cliente.

La función ignore_user_abort() de PHP controla si un script continúa ejecutándose después de que el cliente (el navegador del usuario) se desconecta. Esta página explica qué hace la función, su firma y valor de retorno, cómo funciona junto con connection_aborted(), los errores comunes y un ejemplo completo de tarea en segundo plano.

Qué hace ignore_user_abort()

Cuando un usuario cierra la pestaña del navegador, pulsa Stop o navega a otra página, la conexión con el servidor se interrumpe. Por defecto, PHP no detiene el script en el instante en que esto ocurre — solo detecta la conexión caída la próxima vez que intenta enviar salida al navegador, momento en el que termina el script. ignore_user_abort() cambia ese comportamiento: al habilitarla, PHP continúa ejecutando el script hasta el final aunque ya nadie esté escuchando.

Esto es importante para operaciones que no deben quedar a medias — escribir en una base de datos, procesar un pago, enviar un correo electrónico o generar un informe. Si el usuario se desconecta a mitad del proceso, generalmente se desea que el trabajo se complete en lugar de dejar el sistema en un estado inconsistente.

Un "abort del cliente" es un evento a nivel de transporte: PHP lo detecta solo cuando intenta escribir en una conexión que ya está cerrada. Por eso el momento de detección parece indirecto — consulta Por qué el abort se detecta tarde más abajo.

Sintaxis

ignore_user_abort(?bool $enable = null): int
  • $enable — pasa true para ignorar las desconexiones del cliente, o false para restaurar el comportamiento predeterminado (abortar al desconectarse). Si se omite el argumento, la configuración actual no cambia y solo se devuelve.
  • Valor de retorno — la configuración anterior como un entero (1 = estaba ignorando aborts, 0 = no lo estaba). Esto permite guardar y restaurar el estado.
<?php
$previous = ignore_user_abort(true);   // turn it on, remember old value
// ... critical work ...
ignore_user_abort($previous);          // restore whatever it was before

La misma configuración puede establecerse globalmente en php.ini con la directiva ignore_user_abort; llamar a la función la sobreescribe para la solicitud actual.

Uso básico

Llama a la función una vez cerca del inicio del trabajo que deseas proteger:

<?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);

Ten en cuenta que ignore_user_abort() mantiene el script activo, pero no elimina el límite max_execution_time de PHP. Una tarea de larga duración aún puede ser interrumpida por el límite de tiempo, así que combínala con set_time_limit() cuando sea necesario.

Detectar el abort con connection_aborted()

Ignorar un abort no significa que no puedas reaccionar ante él. La función connection_aborted() devuelve 1 cuando el cliente se ha desconectado y 0 en caso contrario, por lo que puedes comprobarlo dentro de un bucle y decidir si continuar, limpiar y salir.

Un detalle importante: PHP solo actualiza el estado de la conexión cuando intenta enviar salida y se vacía el buffer. Por tanto, para detectar un abort dentro de un bucle normalmente se hace un echo de algo y se llama a flush(), lo que obliga a PHP a detectar el socket cerrado.

<?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);

Aquí connection_aborted() permite que el script decida por sí mismo: puede terminar silenciosamente, registrar que el usuario se fue, o salir antes de tiempo. Relacionado: connection_status() reporta los tres estados (normal, abortado, tiempo agotado) como una máscara de bits.

Un ejemplo práctico de tarea en segundo plano

Un patrón habitual consiste en enviar la respuesta, cerrar la conexión para que el navegador deje de esperar, y luego continuar con trabajo pesado en segundo plano. ignore_user_abort(true) es lo que hace que la parte de "continuar" funcione.

<?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();

El navegador recibe una respuesta rápida y deja de cargar, mientras el servidor termina el trabajo lento. Sin ignore_user_abort(true), ese trabajo en segundo plano se interrumpiría en el momento en que PHP detectara la conexión cerrada.

Por qué el abort se detecta tarde

PHP almacena la salida en un buffer. Hasta que ese buffer se vacía hacia el cliente, PHP no tiene razón para acceder al socket y, por tanto, nunca sabe que está cerrado. Por eso los scripts que no producen salida (o cuya salida permanece en el buffer) pueden ejecutarse hasta completarse tras una desconexión sin que connection_aborted() === 1 se active nunca. Si necesitas detectar aborts de forma oportuna, emite una pequeña señal de actividad y llama a flush() periódicamente, como en el bucle anterior. Las funciones auxiliares de buffer de salida como ob_flush() y ob_end_flush() te dan un control más preciso sobre cuándo los datos salen del buffer.

Errores comunes

  • No anula el límite de tiempo. Usa set_time_limit(0) (o un valor generoso) junto a ella para tareas largas.
  • La detección requiere salida + flush. connection_aborted() no cambiará a 1 por sí solo si el script nunca escribe al cliente.
  • Un script descontrolado es más difícil de detener. Con los aborts ignorados, un bucle infinito con errores sigue consumiendo recursos porque el usuario ya no puede cancelarlo. Combínala siempre con límites razonables.
  • Los scripts CLI no se ven afectados. No hay conexión de cliente en la línea de comandos, por lo que la función no tiene efecto allí — úsala en contextos web (de solicitud).

Conclusión

ignore_user_abort() mantiene un script PHP en ejecución después de que el cliente se desconecta, lo cual es esencial para completar de forma segura trabajos críticos o en segundo plano. Combínala con connection_aborted() para detectar desconexiones, flush() para forzar esa detección, y set_time_limit() para evitar que la tarea sea interrumpida a mitad, y tendrás un patrón fiable para trabajos que no deben quedar incompletos.

Práctica

Práctica
¿Qué hace la función ignore_user_abort() en PHP?
¿Qué hace la función ignore_user_abort() en PHP?
Was this page helpful?