UPDATE
Способ обработки этого случая - комбинация буферизации вывода и соответствующих заголовков HTTP.
Из раздела спецификации HTTP / 1.1 14.10 :
HTTP / 1.1 определяет опцию «закрыть» соединение для отправителя
сигнал о том, что соединение будет закрыто после завершения
ответ.
Итак, если мы передадим заголовок HTTP Content-Length в дополнение к Connection: close , браузер узнает, что закрыть соединение после получения указанной длины ответа:
- Буферизировать ВСЕ выходные данные скрипта, чтобы сохранить возможность отправки заголовков
- Получив полные выходные данные, отправьте соответствующие заголовки клиенту
- Продолжите обработку ... но не пытайтесь отправить вывод, иначе вы получите ошибки, потому что заголовки отправлены.
Кроме того, будьте осторожны, так как вы можете столкнуться с ограничениями по времени выполнения скрипта на веб-сервере SAPI, если вы выполняете слишком много обработки. Наконец, вы должны указать PHP игнорировать «прерывание пользователя» в этом конкретном сценарии, используя ignore_user_abort()
, потому что браузер закроет соединение в результате того, что вы делаете, и вы хотите, чтобы PHP продолжил обработку .
<?php
ignore_user_abort();
ob_start();
// do stuff, generate output
// get size of the content
$length = ob_get_length();
// tell client to close the connection after $length bytes received
header('Connection: close');
header("Content-Length: $length");
// flush all output
ob_end_flush();
ob_flush();
flush();
// close session if you have one ...
// continue your processing tasks ...
?>
Вы можете изучить раздел руководства PHP по Обработка соединений docs .
Кроме того, почему бы не начать буферизацию вывода? Затем вы можете захватить все выходные данные, которые затем будут отправлены, а затем решить, хотите ли вы что-нибудь с ним сделать.
<?php
echo 'before output buffering';
ob_start();
echo 'after output buffering';
$output = ob_get_contents();
// script's only output to this point will be 'before output buffering'
// I changed my mind, send the output ...
ob_end_flush();
?>