Эта тема на forum.dklab.ru


Quantum: Как отключить серфера и продолжить работу скрипта?
Приветствую!
Вообщем сабж. В конце скрипта стоят функции сбора статистики. Хотелось бы сделать flush() отключить серфера и продолжить работу скрипта.
Вот так не катит:
<?php
echo "Hello!";
register_shutdown_function(staticstic);
flush();
exit();

function staticstic()
{
sleep(10);
file_put_contents("testab.txt","test");
}
?>
работает так же, как если поменять exit() на staticstic()
Юрий Насретдинов:
Quantum
ignore_user_abort()
Quantum:
ignore_user_abort()
Это понятно. Продолжает работу скриптов даже если серфер жмет аборт.
А мне интересно его самому по инициативе скрипта отключить и продолжить работу.
Закрыть сокет.
Похоже на пхп никак.
Юрий Насретдинов:
Quantum
А как насчёт


fclose(STDOUT);


?
Quantum:
не работает. И константы с хэндлером стандартного вывода я не нашел в мане.
Юрий Насретдинов:
Quantum
Ну, в принципе, если обращаться к файлу с названием "php://output", то можно даже вывод буферизовать, согласно той же документации.
Quantum:
Нет не помогает. Надо вывести код конца :) для для http это проде \r\n\r\n.
Покапался более основательно в буржунете. Везде советуют запуcкать параллельно скрипт аля
exec("php myscript.php > out.txt"); Или любую другую команду, главнее направив вывод в фаил.
dimagolov:
не совсем по теме, но близко.
Всегда пускайте Output Buffer. Обнаружил на Apache 2.2 Win32, что скпипт без ob_start ЖДЕТ пока клиент заберет вывод и только после этого продолжает вывод.
Отдавал файлы 2-3 метра (JS массивы выводимые через echo). Так как сетка WiFi и/или тестовый ноут тормозил, то вывод без буферизации занимал около 18-20 секунд, а с ней менее одной секунды. Ну а на клиенте конечно время загрузки от самой буферизации не уменьшалось, уменьшалось тогда, когда пускал gzip вывода.
П.С. такое переносит только подгрузка через iframe. Когда делал через ajax и либа пускала eval (передача через JSON) на массив в 2 метра, то клиент умирал минут на 5, правда потом оживал успешно.

в общем идея почитать внимательно про Output Buffer, может можно как-то через него сказать апачу что все уже отправили.

хотя... если посмотреть с другой стороны, то что делать апачу? он пустил handler-а php, который ему что-то отдает, а потом хоть отдавать и перестает, но дохнуть отказывается. как ему догадаться, что кино кончилось и больше ждать нечего? но не килять процесс php при этом?

п.с. а сервер под чем? под *nix-ами или под виндой?
Quantum:
хотя... если посмотреть с другой стороны, то что делать апачу? он пустил handler-а php, который ему что-то отдает, а потом хоть отдавать и перестает, но дохнуть отказывается. как ему догадаться, что кино кончилось и больше ждать нечего? но не килять процесс php при этом?
ну ignore_user_abort() именно так и работает, только инициатором явлеятся удаленная сторона. А тут надо с этой стороны конект порвать.

п.с. а сервер под чем? под *nix-ами или под виндой?
По никсами. ДА вообще идея в том чтобы не плодить лишних процессов для учета статистики, а именно так везде советуют. Вообщем смысла тогда нет. Пускай серфер ждет :)
dimagolov:
Quantum
почитайте http://www.php.net/manual/ru/features.connection-handling.php#71172
так как он подразумевает отправку header, то это можно реализовать, к примеру, картинкой в 1 пиксель, которая будет инициировать запуск статистики и получать connection close в ответ.
Юрий Насретдинов:
Кстати, а нельзя с помощью JavaScript заставить _клиента_ самому "нажать на кнопку Stop"?
dimagolov:
Юрий Насретдинов, по-моему JS такого не умеет. разве что редирект на другую страницу, что даже хуже решения на картинке.
Quantum:
dimagolov Пример по ссылке

<?php
header("Connection: close");
ob_start();
phpinfo();
ignore_user_abort(true);
$size=ob_get_length();
header("Content-Length: $size");
ob_end_flush();
flush();
// Do processing here
sleep(15);
file_put_contents("test.txt",'Text user will never see');
?>

Работает! :) правда только для cgi варианта :(
Картинки тоже дают ограничение - могут быть выключены, может быть выключен js, которые формирует вывод картинки, боты не грузят картинки...
Получатся, что надо делать промежуточную таблицу, сваливать туда всю статистику, а другой слонячий скрипт, не спехом равномерно будет разгребать.
Юрий Насретдинов есть window.stop(), но работает только в нетскейп подобных, причем она не только рвет коннект, но и завершает анализ загруженного документа.
Гость:
А если сбор статистики через register_shutdown_function вызывать?

Эта тема на forum.dklab.ru