Флеш PHP прекратил сбрасывать в IIS7.5 - PullRequest
7 голосов
/ 24 августа 2011

Мы использовали php flush для «очистки» страницы сразу после ее нажатия, а также для отправки элементов навигации и основных компонентов страницы, чтобы страница появлялась почти мгновенно, хотя иногда содержание может занятьдолгое время загрузки.

Это работает очень хорошо.

Недавно мы обновили 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 очищать данные?

Ответы [ 7 ]

28 голосов
/ 19 мая 2012

Существует другой способ установить предел ответа с помощью диспетчера IIS:

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

Большой Pro в том, что вы можете редактировать свойства для всего, не только для PHP, а также для работы с различными версиями (или даже установками одной и той же версии) PHP.

НТН

7 голосов
/ 21 мая 2012

Вы должны установить значение 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.

4 голосов
/ 24 апреля 2012

Введите следующую команду от имени администратора в Powershell:

C:\Windows\System32\inetsrv> .\appcmd.exe set config /section:handlers "/[name='PHP_via_FastCGI'].ResponseBufferLimit:0"

Ожидаемый результат:

Применены изменения конфигурации в разделе "system.webServer / handlers" для "MACHINE / WEBROOT / APPHOST" при настройке comm it path "МАШИНА / WEBROOT / APPHOST"

Для получения дополнительной информации посмотрите: http://www.coastrd.com/cgioniis7

По сути, нам нужно сообщить FastCGI об изменении его ResponseBufferLimit. Это невозможно сделать через консоль управления IIS (только проверено 7.5)

4 голосов
/ 24 августа 2011

Я использую следующую функцию:

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):

<?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";
?>
2 голосов
/ 16 апреля 2013

Я немного опоздал на вечеринку, но подумал, что добавлю, как это сделать с помощью 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>
1 голос
/ 24 августа 2011

Веб-сервер сам решает, будет ли он обрабатывать содержимое или отправлять его по частям. Таким образом, хотя 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()
{
  ....
} 
0 голосов
/ 09 ноября 2016

Вот еще один способ сделать это с помощью 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...