Intereting Posts

Как остановить PHP от отправки данных клиенту, пока все еще запущен PHP-код на сервере?

Этот вопрос подошел ко мне, когда я столкнулся с ошибкой, которая заставила мою программу PHP зацикливаться бесконечно. Вот пример ситуации:

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

Я думаю, что этот «метод» может быть полезен, так что клиент не будет ждать в течение трудоемких процессов, поэтому предотвращает тайм-ауты.

Кроме того, можно ли это решить с помощью HTTP-методов?

Related of "Как остановить PHP от отправки данных клиенту, пока все еще запущен PHP-код на сервере?"

Да.

Это можно легко сделать без асинхронной обработки, если вы правильно используете заголовки HTTP.

В обычных условиях PHP прекратит обработку, как только клиент на другом конце закроет соединение. Если вы хотите продолжить обработку после этого события, вам нужно сделать одно: скажите PHP, чтобы игнорировать прерывания пользователя. Как?

ignore_user_abort()

Это позволит вашему скрипту продолжать работать даже после того, как клиент получит черту из уклонения. Но мы также сталкиваемся с проблемой того, как сообщить клиенту, что выполненный им запрос завершен, чтобы закрыть соединение. Обычно PHP прозрачно обрабатывает отправку этих заголовков для нас, если мы их не укажем. Здесь, однако, нам нужно сделать это явно или клиент не будет знать, когда мы хотим, чтобы они перестали читать ответ.

Чтобы сделать это, мы должны отправить соответствующие заголовки HTTP, чтобы сообщить клиенту, когда нужно закрыть:

 Connection: close Content-Length: 42 

Эта комбинация заголовков сообщает клиенту, что после того, как он прочитает 42 байта ответа тела тела, сообщение завершено и что они должны закрыть соединение. Для этого метода есть несколько следствий:

  1. Вы должны сгенерировать свой ответ ПЕРЕД отправкой любого результата, потому что вы должны определить его размер длины содержимого в байтах, чтобы вы могли отправить правильный заголовок.
  2. Вы должны на самом деле отправить эти заголовки, прежде чем вы эхо отзываете.

Таким образом, ваш скрипт может выглядеть примерно так:

 <?php ignore_user_abort(); // do work to determine the response you want to send ($responseBody) $contentLength = strlen($responseBody); header('Connection: close'); header("Content-Length: $contentLength"); flush(); echo $responseBody; // --- client will now disconnect and you can continue processing here --- 

Большой «Gotchya» с этим методом заключается в том, что при запуске PHP в веб-SAPI вы можете легко преодолеть максимальную директиву по времени, если вы занимаетесь трудоемкой обработкой после того, как клиент конечного пользователя закрывает соединение. Если это проблема, вам может потребоваться рассмотреть возможность асинхронной обработки, используя cron, потому что нет ограничений по времени, когда PHP работает в среде CLI. Кроме того, вы можете просто ограничить время своих сценариев в веб-среде, используя документы set_time_limit .

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

Я сталкиваюсь с той же проблемой, когда я загружаю изображение на twitter & facebook с iphone через веб-сервис php.

Если время обработки загрузки изображения не так много, вы можете проверить комментарий @Musa это может вам помочь, но если для обработки потребуется слишком много времени, попробуйте выполнить эти действия.

  1. Image store in folder 2. Fetch image from folder using cron 3. Cron run for every 2 min in backend 

это уменьшит время обработки.

Надеюсь, это поможет вам.

Целесообразно делать это асинхронно. То есть, создайте другой скрипт, который обрабатывает только созданные ранее файлы tmp и запускает его с помощью cron (даже не включая apache). Когда php работает как модуль веб-сервера, он должен быть предназначен для быстрого формирования ответа, а затем уйти, чтобы высвободить ресурсы для следующего запроса.

Вы поступаете правильно, думая таким образом; просто продолжайте идти по одному маленькому архитектурному шагу дальше и полностью откройте запрос от тяжелого подъема, который должен произойти.

Вы можете сделать это несколькими способами #

1 #

 ob_start(); //output header("Content-Length: ".ob_get_length()); header("Connection: close"); ob_end_flush(); //do other stuff 

2 #

Используя system () или exec () PHP, закройте Process

3 #

Закройте процесс, используя Shell Script

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

Ссылаться на

Как реализовать этот сценарий с помощью PHP?

ИЛИ

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

И вы также должны попытаться минимизировать время загрузки.