PHP скрипт продолжает работать после закрытия страницы [инициировано из AJAX]

Все, что я Google, говорит мне, что это должно не происходит, однако это так.

Я создаю инструмент миграции для создания «основной базы данных». У меня есть панель администратора, доступная только немногим избранным. Есть кнопка слияния, которая запускает вызов AJAX для запуска функции миграции php. Я не уверен, сколько времени занимает этот сценарий, учитывая, что я все еще его разрабатываю, но тем не менее я ожидаю минимум 20 минут, как только он будет запущен в производство и заполнен рабочей базой данных. Мне НЕ нужна лекция о лучших практиках, говорящая мне не делать это через графический интерфейс. Это также станет кроной, однако я хочу иметь возможность вызывать его вручную, если администратор этого пожелает.

Итак, вот мой процесс. Функция миграции немедленно закрывает сессию session_write_close() что позволяет мне запускать несколько сценариев PHP одновременно. Я делаю это, потому что я запускаю setInterval, который проверяет, чтобы увидеть переменную сеанса. Это мой «прогресс», который является просто инту на той итерации цикла, на которой я нахожусь. В моем сценарии миграции я открываю сессии, добавляю 1 к этому int и снова закрываю сессии. Я делаю это в конце каждого цикла.

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

Если я закрываю 100% из своего браузера или очищаю свои сессии, я больше не вижу прогресса в повышении. Это, однако, не потому, что скрипт останавливается. Это связано с тем, что мои индикаторы выполнения зависят от сеансов, и как только я очищаю свои сеансы или закрываю свой браузер, мой файл cookie сеанса изменяется. Однако я знать скрипт все еще работает, потому что я могу запросить базу данных вручную и увидеть, что записи добавляются.

СЕЙЧАС на мой вопрос:
Я не хочу это. Если мой браузер закрывается, если я нажимаю «Обновить», если я теряю соединение и т. Д., Я хочу, чтобы скрипт был ПРЕКРАЩЕН. Я хочу, чтобы это остановило середину процесса.

Я попытался ignore_user_abort (false); однако я уверен, что это относится к командной строке и не имеет никакого значения для меня.

Я хочу, чтобы оно было прервано, потому что я создаю функцию «Ход выполнения», где мы можем выбрать, где возобновить процесс миграции.

Какие-либо предложения?

ОБНОВИТЬ:

Я не хотел идти этим путем, но какое-то решение, о котором я только что думал, могло бы иметь другую переменную сеанса. И это мой «последний раз, когда клиент был проверен», который может быть отметкой времени. В моем javascript на стороне клиента каждые 30 секунд я мог нажать php-скрипт, чтобы «обновить в последний раз, когда клиент был проверен». И в моей функции миграции в начале каждого цикла я мог убедиться, что отметка времени не соответствует 60 секундам, например. Если ему 60 секунд или больше, я делаю кубик, тем самым останавливая свой сценарий. Это локально будет означать «если клиент не обновляет эту временную метку, то мы можем предположить, что пользователь закрыл свой браузер / вкладку / обновил». А что касается функции, я могу игнорировать эту проверку в командной строке (cron). Не идеальное решение, но это мой план Б

0

Решение

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

По сути, это то, что я сделал:

С клиента, в javascript, я настраивал setInterval для запуска каждые 1.5 секунды, и он запускает скрипт php через AJAX. Этот php-скрипт обновляет переменную сеанса с текущей отметкой времени (это может быть легко значение базы данных, если вам нужно, однако я не хотел накладных расходов на другой запрос).

$_SESSION['migration_listsync_clientLastPing_'.$decodedJson['progressKey']] = time();

Затем внутри своей функции миграции я запускаю проверку, чтобы узнать, не старше ли «отметки времени» более 10 секунд, и если это так, я умру — тем самым убив скрипт.

if(isset($_SESSION['migration_listsync_clientLastPing_'.$progressKey])){
$calc = time() - $_SESSION['migration_listsync_clientLastPing_'.$progressKey];
if($calc > 10){
die();
}
}

Я добавил параметр «progressKey», который представляет собой случайное число от 1 до 100, которое генерируется при вызове функции. Этот номер генерируется в javascript и передается в оба моих AJAX-вызова. Таким образом, если пользователь обновит страницу, а затем сразу же снова нажмет кнопку, у нас не будет 2 запущенных функций. «Старый» экземпляр умрет через несколько секунд, и новый экземпляр вступит во владение.

Это не идеальное решение, но эффективное.

1

Другие решения

Других решений пока нет …