Записи с меткой «магия»
Как закрыть соединение и продолжить выполнение скрипта 08.04.2011 PHP
Порой перед разработчиком встает задача проделать действительно долгую операцию после отображения страницы, как например рассылка почтовых сообщений или обмен данными с удаленным сервером. Можно положить эту задачу на плечи крона, но если это не удобно/медленно/кошерно, приходится выкручиваться и изобретать странные решения. Одним из таких решений является выполнение долгой операции непосредственно после рендеринга страницы, что может подвесить соединение на пару (десятков, сотен) секунд, или, если поступить добросовестно и оборвать соединение, пройдет незаметно для пользователя. Об этом методе сегодня и поговорим.
Если обратится к спецификации HTTP, можно найти пару замечательных заголовков:
Connection: close - говорит браузеру оборвать соединение при достижении конца файла Content-Length: n - устанавливает длину документа
Посмотрим реализацию на PHP
-
(0);
-
(true);
-
-
(); // start buffer
-
-
// out page content
-
"This make take some time, please wait";
-
-
$length = ();
-
-
// magic
-
('Connection: close');
-
("Content-Length: " . $length);
-
("Content-Encoding: none");
-
("Accept-Ranges: bytes");
-
-
();
-
();
-
();
-
-
// background
-
-
"if you see this, i am not working =(";
-
-
//long, long operation
-
-
for ($i = 0; $i <= 100000; $i++) {
-
("me@localhost", "spam", $i);
-
}
Не забывайте про параметр max_execution_time в php.ini, которым ограничено время выполнения вашего скрипта. Content-Encoding установлен в none для того, что бы исключить изменения размера gzip модулями сервера, что приведет к неверной работе. Впрочем это не гарантирует 100% решение проблемы, так что используйте этот трюк с умом.