Может ли скрипт PHP заставить браузер думать, что HTTP-запрос окончен? - PullRequest
6 голосов
/ 17 сентября 2009

Сначала я настраиваю свой сценарий для запуска даже после окончания HTTP-запроса

 ignore_user_abort(true);

затем удалите текст.

 echo "Thats all folks!";
 flush();

Теперь, как заставить браузер думать, что HTTP-запрос завершен? так что я могу продолжать делать свою собственную работу без браузера, показывающего «загрузка страницы».

 header(??) // something like this?

Ответы [ 5 ]

10 голосов
/ 19 сентября 2009

Вот как это сделать. Вы просите браузер прочитать первые N символов вывода, а затем закрыть соединение, пока ваш скрипт продолжает работать до тех пор, пока не будет завершен.

<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort(true); // optional
ob_start();
echo ('Text the user will see');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush();     // Will not work
flush();            // Unless both are called !

// At this point, the browser has closed connection to the web server

// Do processing here
echo('Text user will never see');
?>
4 голосов
/ 17 сентября 2009

Может быть, этот конкретный комментарий на странице справки php.net поможет: http://www.php.net/manual/en/features.connection-handling.php#71172

4 голосов
/ 17 сентября 2009

Заголовки не будут работать (это заголовки, поэтому они приходят сначала )

Я не знаю ни одного способа закрыть http-соединение без завершения сценария, хотя, полагаю, есть какой-то неясный способ сделать это.

Сообщение о том, что вы хотите сделать после выполнения запроса, поможет нам дать лучшие предложения.

Но в общем, я бы подумал об одном из следующих:

1) Выполнить некоторый простой сценарий командной строки (с использованием exec ()), который выглядит следующим образом:

#!/bin/sh
php myscript.php <arg1> <arg2> .. <argN> &

Затем начните это с вашего http-скрипта, например:

<?PHP
exec('/path/to/my/script.sh');
?>

Или:

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

В конце концов, вы не хотите, чтобы ваш скрипт продолжал выполняться после http-запроса. Предполагая, что вы используете mod_php, это означает, что вы будете связывать процесс apache до тех пор, пока скрипт не завершится.

2 голосов
/ 17 сентября 2009

Лучший способ сделать это - использовать буферизацию вывода. PHP отправляет заголовки, когда все хорошо и готово, но если вы перенесете свой вывод в браузер с помощью ob_ *, вы сможете контролировать заголовки на каждом этапе пути.

Если хотите, вы можете держать отрендеренную страницу в буфере и отправлять заголовки, пока в Китае не взойдет солнце. Именно из-за этой практики вы можете увидеть множество открывающих тегов <?php, но в настоящее время нет закрывающих тегов. Он не позволяет сценарию отправлять заголовки преждевременно, поскольку некоторые из них могут быть учтены.

2 голосов
/ 17 сентября 2009

Теоретически, если HTTP 1.1 keep-alive включен, и клиент получает количество символов, которое он ожидает от сервера, он должен обработать его как конец ответа и продолжить и отобразить страницу (сохраняя соединение по-прежнему). открыть.) Попробуйте отправить эти заголовки (если вы не можете включить их другим способом):

Connection: keep-alive
Content-Length: n

Где n - количество символов, которое вы отправили в теле ответа (выходная буферизация может помочь вам это подсчитать). Извините, у меня нет времени, чтобы проверить это самостоятельно. Я просто добавляю предложение на случай, если оно сработает.

...