Примечание для пользователей mod_fcgid (пожалуйста, используйте на свой страх и риск).
Быстрое решение
Принятый ответ Джоэри Себрехтса действительно работает. Однако, если вы используете mod_fcgid, вы можете обнаружить, что это решение не работает само по себе. Другими словами, когда вызывается функция очистки, соединение с клиентом не закрывается.
FcgidOutputBufferSize
Параметр конфигурации mod_fcgid может быть виноват. Я нашел этот совет в:
- этот ответ Трэверс Картер и
- это сообщение в блоге Seumas Mackinnon .
Прочитав вышесказанное, вы можете прийти к выводу, что быстрым решением было бы добавить строку (см. «Пример виртуального хоста» в конце):
FcgidOutputBufferSize 0
в файле конфигурации Apache (например, httpd.conf), в файле конфигурации FCGI (например, fcgid.conf) или в файле виртуальных хостов (например, httpd-vhosts.conf).
В пункте (1) выше упоминается переменная с именем "OutputBufferSize". Это старое имя, FcgidOutputBufferSize
упомянутое в (2) (см. Примечания к обновлению на веб-странице Apache для mod_fcgid ).
Детали и второе решение
Вышеупомянутое решение отключает буферизацию, выполняемую mod_fcgid для всего сервера или для определенного виртуального хоста. Это может привести к снижению производительности вашего веб-сайта. С другой стороны, это может быть не так, поскольку PHP выполняет буферизацию самостоятельно.
Если вы не хотите отключать буферизацию mod_fcgid , есть другое решение ... вы можете принудительно очистить этот буфер .
Приведенный ниже код делает именно это, основываясь на решении, предложенном Джоэри Себрехтсом:
<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort(true); // just to be safe
ob_start();
echo('Text the user will see');
echo(str_repeat(' ', 65537)); // [+] Line added: Fill up mod_fcgi's buffer.
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Strange behaviour, will not work
flush(); // Unless both are called !
// Do processing here
sleep(30);
echo('Text user will never see');
?>
По сути, добавленная строка кода заполняет буфер mod_fcgi , заставляя его очищаться . Число «65537» было выбрано, потому что значение FcgidOutputBufferSize
переменной по умолчанию - «65536», как указано на веб-странице Apache для соответствующей директивы . Следовательно, вам может потребоваться изменить это значение соответствующим образом, если в вашей среде установлено другое значение.
Моя среда
- WampServer 2.5
- Apache 2.4.9
- PHP 5.5.19 VC11, x86, без защиты потоков
- mod_fcgid / 2.3.9
- Windows 7 Профессиональная x64
Пример виртуального хоста
<VirtualHost *:80>
DocumentRoot "d:/wamp/www/example"
ServerName example.local
FcgidOutputBufferSize 0
<Directory "d:/wamp/www/example">
Require all granted
</Directory>
</VirtualHost>