При запуске PHP, и вы хотите, чтобы он немедленно возвратил HTML в браузер, закрыл соединение (ish) и затем продолжил обработку …
Следующее работает, когда соединение HTTP / 1.1, но не при использовании Apache 2.4.25
, с mod_http2
включен, и у вас есть браузер, который поддерживает HTTP / 2 (например, Firefox 52 или Chrome 57).
Что происходит, Connection: close
Заголовок не отправлен.
<?php
function http_connection_close($output_html = '') {
apache_setenv('no-gzip', 1); // Disable mod_gzip or mod_deflate
ignore_user_abort(true);
// Close session (if open)
while (ob_get_level() > 0) {
$output_html = ob_get_clean() . $output_html;
}
$output_html = str_pad($output_html, 1023); // Prompt server to send packet.
$output_html .= "\n"; // For when the client is using fgets()
header('Connection: close');
header('Content-Length: ' . strlen($output_html));
echo $output_html;
flush();
}
http_connection_close('<html>...</html>');
// Do stuff...
?>
Для похожих подходов к этой проблеме, см .:
И почему connection
заголовок удален, документация для nghttp2
библиотека (как используется Apache) заявляет:
https://github.com/nghttp2/nghttp2/blob/master/doc/programmers-guide.rst
HTTP/2 prohibits connection-specific header fields. The
following header fields must not appear: "Connection"...
Так что, если мы не можем сказать браузеру закрыть соединение через этот заголовок, как нам заставить это работать?
Или есть другой способ сообщить браузеру, что у него есть все для ответа HTML, и что он не должен продолжать ждать поступления новых данных.
Этот ответ работает только тогда, когда веб-сервер общается с PHP через FastCGI
протокол.
Чтобы отправить ответ пользователю (веб-сервер) и возобновить обработку в фоновом режиме, без участия вызовов ОС, вызовите fastcgi_finish_request()
функция.
<?php
echo '<h1>This is a heading</h1>'; // Output sent
fastcgi_finish_request(); // "Hang up" with web-server, the user receives what was echoed
while(true)
{
// Do a long task here
// while(true) is used to indicate this might be a long-running piece of code
}
php-fpm
дочерний процесс будет занят и не может принимать новые запросы, пока они не закончили с обработкой этой длительной задачи.Если все доступно php-fpm
дочерние процессы заняты, тогда ваши пользователи будут испытывать зависание страницы. Используйте с осторожностью.
nginx
а также apache
оба сервера знают, как бороться с FastCGI
протокол, поэтому не должно быть никаких требований по обмену apache
сервер для nginx
,
Вы можете обслуживать свои медленные PHP-скрипты через HTTP / 1.1, используя специальный поддомен.
Все, что вам нужно сделать, это установить второй VirtualHost, который отвечает HTTP / 1.1, используя директиву Apache Protocols: https://httpd.apache.org/docs/2.4/en/mod/core.html#protocols
Большим преимуществом этой техники является то, что ваши медленные сценарии могут отправлять некоторые данные в браузер задолго до того, как все остальное было отправлено через поток HTTP / 2.