Запускай php скрипт так долго в фоновом режиме в героку

У меня есть скрипт PHP, который отправляет сообщения в список пользователей, который я размещал в Heroku. Теперь я хотел добавить задержку между этими сообщениями. Скажите, как, 6 минут промежуток между каждым сообщением. Так что, если есть 90 пользователей, этот сценарий должен работать в фоновом режиме в течение 9 часов.

Я попытался вызвать этот скрипт с помощью ajax, поэтому он работает в фоновом режиме и добавив sleep(360); внутри цикла for, чтобы получить 6-минутную задержку. Но он работает только для 10-20 пользователей, после чего останавливается.

foreach ($users_list["users"] as $key => $value) {
try{
....
code for sending message
.....

}catch(Exception $e){
continue;
}
sleep(360);
}

Поэтому я хотел бы знать, каков оптимальный способ добиться этого в Heroku.

1

Решение

Вызов скрипта с использованием AJAX не вызывает его в фоновом режиме, он просто запускает его асинхронно со страницы, на которой вы находитесь. Другими словами, он все еще работает в Apache, имеет какие-либо данные сеанса и все еще ограничен настройками тайм-аута PHP и Apache.

Чтобы запустить его действительно в фоновом режиме, вы можете использовать что-то вроде CRON

Или, если вам разрешено на вашем сервере, вы можете вызвать его из командной строки, как с exec или же shell_execЕсть также несколько других аналогичных функций, таких как popen, system и т.д. Все они делают вещи немного по-другому.

Некоторые экологические вещи будут отличаться, и это может оказать большое влияние на ваш код. Например, много вещей в $_SERVER не установлен или имеет другую информацию. Например, там может отсутствовать IP-адрес сервера, у вас не будет никаких сессионных вещей. Вы не сможете использовать $_GET или же $_POST но может получить входные данные (из вызова командной строки) из $argv массив, первый элемент — путь к файлу … и т. д.

В основном вам нужно назвать это так:

 exec('php -f "path/to/php/file.php" "arg1" "arg2"');

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

Чтобы сделать еще один шаг вперед и сделать его неблокирующим, вы можете добавить его (в Linux)

exec('php -f "path/to/php/file.php" "arg1" "arg2" > /dev/null &');

& в конце это самый важный бит.

Теперь для Windows это немного другая игра в мяч. Я имел успех, используя это

$WshShell = new \COM('WScript.Shell');
$cmd = 'cmd /C php "path/to/php/file.php" "arg1" "arg2"';
$WshShell->Run($cmd, 0, false);

Также на Windows, чтобы запустить PHP с просто php Вы должны добавить путь к php.exe ты хочешь использовать для path переменная среды В противном случае вы должны использовать полный путь к exe вместо просто php

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

escapeshellarg

EscapeShellCmd

Я написал класс оболочки для этого вы можете найти на моем GitHub

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

2

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

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