Мы сразу же используем php-флеш для «пустого» страницы, как только он нажимается, а также для отправки навигации и основных компонентов страницы, чтобы страница отображалась почти мгновенно, хотя иногда контент может занять много времени загружать.
Это работает очень хорошо.
Недавно мы обновили с IIS 7.0 до 7.5 и теперь флеш не работает. При исследовании проблемы мы отключили сжатие как для статических, так и для динамических файлов. Мы также отключили кэширование вывода.
У нас также отключено сжатие zlib и вывод буферизации в php.ini.
Чтобы проверить проблему, мы имеем следующий сценарий
@ini_set("output_buffering", "Off"); @ini_set('implicit_flush', 1); @ini_set('zlib.output_compression', 0); ob_start(); echo "starting...<br/>\n"; for($i = 0; $i < 5; $i++) { print "$i<br/>\n"; ob_end_flush(); ob_flush(); flush(); ob_start(); sleep(2); } print "DONE!<br/>\n";
Браузер просто показывает статус загрузки (независимо от того, что находится в любом браузере, в IE он выглядит как анимированный gif Ajax, в Firefox на вкладке будет сказано «Подключение …») в течение 10 секунд, а затем внезапно появится весь вывод.
Мы попытались использовать различные комбинации flush и ob_flush и ob_end_flush, основанные на похожих вопросах на этом сайте. Ни один из них не работает. Есть ли способ сделать IIS / PHP для очистки данных?
Вы должны установить значение ResponseBufferLimit для выбранного обработчика на число, достаточно низкое для фактического сброса. Я рекомендую использовать 0, поскольку он не позволяет IIS ничего делать, кроме как передавать то, что вы отправляете с вашего PHP-скрипта. Вы можете использовать следующую командную строку, чтобы установить ResponseBufferLimit в 0 для обработчика php (просто измените «NAME» на имя обработчика, который вы хотите обновить, например PHP53_via_FastCGI):
appcmd.exe set config /section:handlers "/[name='NAME'].ResponseBufferLimit:0"
Кроме того, вы можете напрямую отредактировать файл applicationHost.config и добавить атрибут ResponseBufferLimit в элемент XML.
Существует еще один способ установить лимит ответа с помощью диспетчера IIS:
Большой Pro – это то, что вы можете редактировать свойства для всего, а не только PHP, и вы можете работать с разными версиями (или даже с установками той же версии) PHP.
НТН
Введите следующую команду в качестве администратора в Powershell:
C:\Windows\System32\inetsrv> .\appcmd.exe set config /section:handlers "/[name='PHP_via_FastCGI'].ResponseBufferLimit:0"
Ожидаемый результат:
Применимые изменения конфигурации к разделу «system.webServer / обработчики» для «MACHINE / WEBROOT / APPHOST» при настройке компилируют его путь «MACHINE / WEBROOT / APPHOST»
Для получения дополнительной информации ознакомьтесь с: http://www.coastrd.com/cgioniis7
В принципе, нам нужно сказать FastCGI о том, чтобы включить ResponseBufferLimit
. Это невозможно сделать с помощью консоли управления IIS (проверено только 7.5)
Что я делаю, так это то, что я использую следующую функцию:
function flush_buffers(){ ob_end_flush(); ob_flush(); flush(); ob_start(); }
Итак, в вашем коде:
ob_start(); flush_buffers(); echo "starting...<br/>\n"; for($i = 0; $i < 5; $i++) { print "$i<br/>\n"; flush_buffers(); sleep(2); }
Он должен работать безупречно 🙂
Вот какой рабочий код (с правильным набором Content-Type
):
DEMO
КОД
<?php header("Content-Type: text/html; charset=utf-8"); function flush_buffers(){ ob_end_flush(); ob_flush(); flush(); ob_start(); } ob_start(); flush_buffers(); echo "starting...<br/>\n"; for($i = 0; $i < 60; $i++) { flush_buffers(); print "$i<br/>\n"; flush_buffers(); sleep(2); } flush_buffers(); print "DONE!<br/>\n"; ?>
Я немного опоздал на вечеринку, но подумал, что добавлю, как это сделать с помощью web.config.
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!--- other stuff here ---> <handlers> <remove name="ISAPI-dll" /> <add name="ISAPI-dll" path="*.dll" verb="*" type="" modules="IsapiModule" scriptProcessor="" resourceType="File" requireAccess="Execute" allowPathInfo="true" preCondition="" responseBufferLimit="0" /> </handlers> </system.webServer> </configuration>
Это зависит от веб-сервера, решит ли он разворачивать контент или отправлять его через закодированную кодировку. Поэтому, хотя PHP может попросить сервер выталкивать данные клиенту, он не может заставить сервер использовать закодированную кодировку.
В этой статье вам явно нужно установить кодировку передачи для IIS (см. Бит об ISAPI) для отправки данных на сервер – вы можете попробовать то же самое в своем скрипте.
IME, большинство сценариев, где это проблема, можно лучше решить ….
register_shutdown_function('do_slow_stuff'); ....generate html content.... exit; // closes stdin/stdout, but shutdown fn will still be called function do_slow_stuff() { .... }
Вот еще один способ сделать это с помощью web.config (метод @ Jules не работал для меня с IIS 8.0). Конечно, вы захотите заменить версии PHP и пути на них на самом деле на вашем компьютере.
Это позволяет использовать сервер-отправленные события!
<configuration> <system.webServer> <handlers> <remove name="PHP53_via_FastCGI" /> <remove name="PHP54_via_FastCGI" /> <remove name="PHP55_via_FastCGI" /> <add name="PHP53_via_FastCGI" path="*.php" verb="GET,HEAD,POST" type="" modules="FastCgiModule" scriptProcessor="C:\Program Files (x86)\PHP\v5.3\php-cgi.exe" resourceType="Either" requireAccess="Script" allowPathInfo="true" preCondition="" responseBufferLimit="0" /> <add name="PHP54_via_FastCGI" path="*.php" verb="GET,HEAD,POST" type="" modules="FastCgiModule" scriptProcessor="C:\Program Files (x86)\PHP\v5.4\php-cgi.exe" resourceType="Either" requireAccess="Script" allowPathInfo="true" preCondition="" responseBufferLimit="0" /> <add name="PHP55_via_FastCGI" path="*.php" verb="GET,HEAD,POST" type="" modules="FastCgiModule" scriptProcessor="C:\Program Files (x86)\PHP\v5.5\php-cgi.exe" resourceType="Either" requireAccess="Script" allowPathInfo="true" preCondition="" responseBufferLimit="0" /> </handlers> </system.webServer> </configuration>