Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Управление выводом

304
29 сентября 2009 года
Fenyx
707 / / 26.01.2005
Всем доброго времени суток. Столкнулся с непоняткой по выоду в пхп
Код:
<?php
ob_start();
for ($i=0; $i<2000; $i++){
 $echo.=$i."\n";
}
echo strlen($echo).$echo;
header("Content-Type: text/html");
header("Content-Length: ".ob_get_length());
header('Connection: close');
ob_end_flush();
sleep(10);
//Дальнейшее выполнение скрипта
?>

Так вот когда размер выводных данных более 8кб скрипт отрабатывает как должен - отдает контент и продолжает работу через 10 секунд но браузер этого уже не знает. Если размер менее 8 кб, то выдача в браузер идет только после sleep. Что влияет на такое поведение?
13
29 сентября 2009 года
RussianSpy
3.0K / / 04.07.2006
Расскажи как ты это отмерял и зачем вообще такая порнография нужна?

[COLOR="Silver"]ЗЫ В чем прикол называть переменные также как встроенные в язык функции и структуры?[/COLOR]
12
30 сентября 2009 года
alekciy
3.0K / / 13.12.2005
Поддерживаю RussianSpy. Метод измерения в студию. Сильно подозреваю, что в итоге придем к буферам браузера.

[COLOR="DimGray"]P.S. В таких случаях крайне рекомендую к использованию какой либо снифер. Лично я за Wireshark.[/COLOR]
366
30 сентября 2009 года
int
668 / / 30.03.2005
Я как-то в инете встречал целую статью на похожую тему, что если размер выводимых данных больше чего-то там, то php начинает протормаживать. Вспомнить бы, где это было.
12
01 октября 2009 года
alekciy
3.0K / / 13.12.2005
Брехня (с)
285
01 октября 2009 года
Romik
479 / / 24.11.2002
А никого не смущает, что сразу отдаётся контент, а потом посылаются заголовки?
304
01 октября 2009 года
Fenyx
707 / / 26.01.2005
Цитата: Romik
А никого не смущает, что сразу отдаётся контент, а потом посылаются заголовки?


Наверно не смущает потому что стоит ob_start.

По методу измерения - путем простого подбора, до тех пор пока контент не отдастся сразу, а не будет ждать завершения выполнения скрипта. Можно изменить в цикле значение на 1500 например и контент не отдастся до завершения скрипта.

Для чего: есть скрипт который выполняется довольно долго, ответ клиенту нужно дать быстро, что мол не волнуйтесь все работает, не прерывая выполнения скрипта. Можно пойти и другими путями, но пока более крсивым кажется этот. Если посладть заголовок Location:/ все равно переход произойдет только после выполнения скрипта.

На основе данного примера все работает, смущает посылка лишних килобайтов, но это не критично (хотя интересно почему). Буфер браузера - возможно, но в таком случае у IE и мозилы одинаковый буфер.

Интесно еще одно поведение даже не знаю кого (браузера или сервера). При таком выводе в том же окне (для IE) или новой вкладке (мозила) браузер отказывается выводить любые страницы с данного домена до тех пор пока работает скрипт (а работать он может очень долго), при чем для нового окна (процесса) все работает нормально.

244
01 октября 2009 года
UAS
2.0K / / 19.07.2006
Помню было у меня что-то подобное и решалось оно добавлением к данному коду обычного flush();
Я правда хз, как это поможет вдруг тебе, но всё же..
304
01 октября 2009 года
Fenyx
707 / / 26.01.2005
Цитата: UAS
Помню было у меня что-то подобное и решалось оно добавлением к данному коду обычного flush();
Я правда хз, как это поможет вдруг тебе, но всё же..


не совсем понимаю где вызывать flush если я вызываю [COLOR=#0000bb][FONT=Courier New]ob_end_flush[/FONT][/COLOR][COLOR=#007700][FONT=Courier New]();[/FONT]
[/COLOR]

13
01 октября 2009 года
RussianSpy
3.0K / / 04.07.2006
Никогда ничего такого не встречал. Наводит на мысли о кривом сервере или некорректных заголовках.

Не проще ли сделать как все белые люди реализуют тот же например прогресс бар? Зачем сношать себе мозг. jQuery в помощь.
244
01 октября 2009 года
UAS
2.0K / / 19.07.2006
Fenyx, как раз в том-то и было дело. Реализовывал, так сказать, "информационную консоль". Т.е. делал граббер, ну и по ходу, чтобы видеть как идет процесс, постепенно в поток выдавал статистику.
Вот как раз там были проблемы, которые почему-то решились только совместным использованием этих обоих flush-функций. Правда, у меня не было ob_start();, т.е. шел сразу вывод в поток.

Вообщем, я сам хз, почему у меня работало тогда только так %) Магия %)
304
01 октября 2009 года
Fenyx
707 / / 26.01.2005
Цитата: RussianSpy
Никогда ничего такого не встречал. Наводит на мысли о кривом сервере или некорректных заголовках.

Не проще ли сделать как все белые люди реализуют тот же например прогресс бар? Зачем сношать себе мозг. jQuery в помощь.


В данной ситуации быстрей и красивей решение выше, т.к в противном случае прийдется полностью переписывать скрипт который достался в наследство (не хочется). А про кривой серв и т.д. легко проверить запустив пример выше со слипом минуту к примеру.

285
01 октября 2009 года
Romik
479 / / 24.11.2002
господа, зачем посылать header("Content-Length: ".ob_get_length()); ? ob_flush() сам обо всё позаботиться. Так как написано код всё равно нельзя посылать, та как в ob-буффер попадают и посылаемые заголовки.
Fenyx, что тебе мешает писать код по-человечески?
[highlight=php]
<?php
ob_start();
header("Content-Type: text/html");
header('Connection: close');
$output = "";
for ($i=0; $i<2000; $i++){
$output.=$i."\n";
}
echo strlen($output).$output;
ob_end_flush();
sleep(10);
//Дальнейшее выполнение скрипта
?>
[/highlight]
304
01 октября 2009 года
Fenyx
707 / / 26.01.2005
Цитата: Romik
господа, зачем посылать header("Content-Length: ".ob_get_length()); ? ob_flush() сам обо всё позаботиться. Так как написано код всё равно нельзя посылать, та как в ob-буффер попадают и посылаемые заголовки.
Fenyx, что тебе мешает писать код по-человечески?


Зачем Content-Length - да затем что бы браузер перестал ждать ответа от сервера. По этой же причине заголовки посылаются ПОСЛЕ формирования контента попавшего в буфер

12
02 октября 2009 года
alekciy
3.0K / / 13.12.2005
Код:
<?php
$echo = '';
ob_start();
for ($i=0; $i < 60; $i++)
{
    $echo .= $i."\n";
}
echo strlen($echo).$echo;

header("Content-Type: text/html");
header("Content-Length: ".ob_get_length());
header('Connection: close');

ob_end_flush();

ob_flush();
flush();

sleep(10);
//Дальнейшее выполнение скрипта
?>
12
02 октября 2009 года
alekciy
3.0K / / 13.12.2005
Цитата: UAS
Fenyx, как раз в том-то и было дело. Реализовывал, так сказать, "информационную консоль". Т.е. делал граббер, ну и по ходу, чтобы видеть как идет процесс, постепенно в поток выдавал статистику.
Вот как раз там были проблемы, которые почему-то решились только совместным использованием этих обоих flush-функций. Правда, у меня не было ob_start();, т.е. шел сразу вывод в поток.

Вообщем, я сам хз, почему у меня работало тогда только так %) Магия %)


Магию оставь циганкам с вокзала ;)

На пути от скрипта до отрисовки страницы в браузере кроме буферов самого PHP (output_buffering) существует масса других буферов. Это и буфера самого апача (к слову в модуле mod_deflate величина DeflateBufferSize по дефолту как раз равна 8кБ), TCP буфера, буфера браузера и черт-еще-знает-какие-в-каждом-конкретном-случае. Поэтому то, что PHP сбросил свои буферы вовсе не значит, что это сделали другие промежуточные звенья. Я не копал исходники PHP, но сильно подозреваю, что ob_flush() сбрасывает буферы самого PHP, а flush() заставляет выполнить сброс промежуточных буферов (скорее всего через какой то системный вызов).

Кроме того чтение манула повышает ум и сообразительность, ум и сообразительность:

Цитата:

Flushes the write buffers of PHP and whatever backend PHP is using (CGI, a web server, etc). This attempts to push current output all the way to the browser with a few caveats.

flush() may not be able to override the buffering scheme of your web server and it has no effect on any client-side buffering in the browser. It also doesn't affect PHP's userspace output buffering mechanism. This means you will have to call both ob_flush() and flush() to flush the ob output buffers if you are using those.

Several servers, especially on Win32, will still buffer the output from your script until it terminates before transmitting the results to the browser.

Server modules for Apache like mod_gzip may do buffering of their own that will cause flush() to not result in data being sent immediately to the client.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог