Intereting Posts

PHP-флеш прекратил промывку в IIS7.5

Мы сразу же используем 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:

  1. На главной странице сервера в разделе «Управление» выберите «Редактор конфигурации»;
  2. в разделе «Раздел» введите «system.webServer / обработчики»;
  3. рядом с «(Коллекция)» щелкните «…» ИЛИ отметьте элемент «(Коллекция)», и в разделе «Действия» und '(Коллекция) «Элемент» нажмите «Редактировать элементы»;
  4. прокрутите страницу вниз до тех пор, пока вы не найдете свою версию PHP под «Имя»;
  5. внизу отображаются свойства, которые могут быть отредактированы вручную, включая responseBufferLimit, который должен быть установлен в 0 для работы flush ().

Большой 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>