Закройте соединение в 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, если у вас есть куча денег и вы хотите испытанное и проверенное решение)