Редактировать: Я был не прав насчет $_SESSION
. Он не обновляется асинхронно, т. Е. Значения, которые вы храните в нем, недоступны до тех пор, пока сценарий не завершится. Упс.
Таким образом, прогресс должен храниться в чем-то, что обновляется асинхронно: в памяти (как предлагает пироскоп и, тем не менее, является лучшим решением), в файле или базе данных.
Другими словами, вместо использования $_SESSION
для хранения значения, оно должно храниться в memcached, в файле или в базе данных.
т.е. используя базу данных
$progress = 0;
mysql_query("INSERT INTO `progress` (`id`, `progress`) VALUES ($uid, $progress)");
# loop starts
# processing...
$progress += $some_increment;
mysql_query("UPDATE `progress` SET `progress`=$progress WHERE `id`=$uid");
# loop ends
Или используя файл
$progress = 0;
file_put_contents("/path/to/progress_files/$uid", $progress);
# loop starts
# processing...
$progress += $some_increment;
file_put_contents("/path/to/progress_files/$uid", $progress);
# loop ends
А затем прочитайте файл / выберите из базы данных, когда запрашиваете прогресс через ajax. Но это не очень хорошее решение по сравнению с memcached.
Кроме того, не забудьте удалить строку файла / базы данных, как только все это будет сделано.
Вы можете поместить прогресс в переменную $_SESSION
(вам понадобится уникальное имя) и обновлять его во время выполнения процесса. Между тем ваш ajax-запрос просто получает эту переменную через определенный интервал
function heavy_process($input, $uid) {
$_SESSION[$uid] = 0;
# loop begins
# processing...
$_SESSION[$uid] += $some_increment;
# loop ends
}
Затем укажите URL, который просто выплевывает значение $_SESSION[$uid]
при запросе через ajax. Затем используйте возвращенное значение, чтобы обновить индикатор выполнения. Используйте что-то вроде sha1(microtime())
, чтобы создать $ uid
Редактировать: решение Pyroscope технически лучше, но если у вас нет сервера с memcached или возможностью запускать фоновые процессы, вы можете использовать $_SESSION
вместо