У меня есть скрипт 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.
Вызов скрипта с использованием 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
В любом случае вы должны быть очень осторожны при вводе данных конечного пользователя в любой вызов командной строки. Есть две функции, чтобы очистить это, но я пытаюсь просто не вставлять это.
Я написал класс оболочки для этого вы можете найти на моем GitHub
Надеюсь, поможет.
Других решений пока нет …