Закройте соединение в PHP, но продолжайте выполнять скрипт

Кто-нибудь знает, как закрыть соединение (кроме просто flush()?), но потом продолжайте выполнять некоторый код.

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

5 ответов

Решение

Вы можете посмотреть на pcntl_fork() - это позволяет вам раскошелиться на ваш текущий скрипт и запустить его в отдельном потоке.

Я использовал его в проекте, где пользователь загружал файл, а затем скрипт выполнял над ним различные операции, в том числе общение со сторонним сервером, что может занять много времени. После первоначальной загрузки сценарий разветвился и отобразил следующую страницу для пользователя, а родительский самоуничтожился. Затем дочерний процесс продолжил выполнение, и возвращаемая страница запросила его статус с помощью AJAX. это сделало приложение намного более отзывчивым, и пользователь получил обратную связь относительно статуса во время его выполнения.

Эта ссылка содержит больше информации о том, как ее использовать:

Если вы не можете использовать pcntl_fork, вы всегда можете вернуться к быстрому возвращению страницы, которая запускает AJAX-запрос на выполнение большего количества элементов из очереди.


mvds напоминает следующее (которое может применяться в конкретной конфигурации сервера): не fork весь веб-сервер Apache, но вместо этого запустите отдельный процесс. Пусть этот процесс раскроет ребенка, который живет дальше. Ищу proc_open чтобы получить полное взаимодействие между вашим PHP-скриптом и процессом.

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

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

Ключевым моментом, на который указывает ответ Jhong и обратное предположение из комментария animusen, является то, что весь смысл того, что мы делаем с HTTP как веб-разработчиками, заключается в том, чтобы отвечать на запрос как можно быстрее / end - вот и все, так что если вы ' Если вы делаете что-то еще, то это указывает на какое-то дизайнерское решение, которое, возможно, могло бы быть немного лучше:)

Как правило, вы берете дополнительную задачу, которую выполняете после возврата "страницы", и передаете ее другому процессу, обычно это означает, что вы помещаете задачу в очередь заданий и выполняете ее с помощью демона или задания cron. необходимо.

Точное решение зависит от того, что вы делаете, и ответ на другой (набор) вопросов; но для этого все сводится к: нет, вы не можете закрыть соединение, и вам бы посоветовали взглянуть на рефакторинг долго выполняющегося процесса из этого скрипта / страницы.

Посмотрите на PHP ignore_user_abort Урегулирование Вы можете установить его, используя ignore_user_abort() функция

Был приведен пример (необязательного) использования (и было сообщено, что ФП работает) в следующем дублирующем вопросе:

Это в основном дает ссылку на заметки пользователя в руководстве по PHP. Центральный является

которая также является основой для следующих двух, я хотел бы предложить вам изучить:

Не fork весь веб-сервер Apache, но вместо этого запустите отдельный процесс. Пусть этот процесс раскроет ребенка, который живет дальше. Ищу proc_open чтобы получить полное взаимодействие между вашим PHP-скриптом и процессом.

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

(вы также можете использовать очередь заданий Zend Server, если у вас есть куча денег и вы хотите испытанное и проверенное решение)

Другие вопросы по тегам