Постоянно запущенный скрипт на PHP, как реализовать?

Требуется по запросу юзера (нажал кнопку) вести отсчет таймера от 120 секунд до 0 и произвести действие. Собственно, если это делать по крону, то тогда у нас будет люфт в одну минуту - а требуется точность (даже если юзер закрыл страницу отсчет идет). Таких таймеров может быть много.

Как это реализовывается на PHP? Спасибо!
  • Вопрос задан
  • 3583 просмотра
Решения вопроса 1
eXcNightRider
@eXcNightRider
FullStack Web Developer | DevOps
Привожу живой пример из личной продакшн практики. PHP-CLI скрипт как запускаемое приложение
Начальные условия:
Наличие GNU Linux (в моём случае это Debian)
Установленные пакет php, php-cli, остальные по вкусу и зависимостям
В качестве таймера используется класс React\EventLoop\Factory
1. Создаём пустой файл, можно без разрешения (например daemon), открываем в текстовом редакторе
Важно, чтобы в начале была строка #!/usr/bin/php -q
2. Пишем
#!/usr/bin/php -q
<?php
ini_set("display_errors", 1);
error_reporting(E_ERROR);
require "/var/project/vendor/autoload.php";
require '/var/project/bin/cli_config.php';
use Ratchet\Session\SessionProvider;

$loop = React\EventLoop\Factory::create();
//вызовы $loop->addPeriodicTimer можно ставить в нужном количестве, первый параметр - количество секунд
$loop->addPeriodicTimer(120, function(){
//код здесь будет выполняться каждые 120 секунд
});
//если нужен повторяющийся цикл 
//$loop->run();
//а если нужен один раз на вызов
$loop->tick();

3. chmod a+x /www/project/bin/daemon - даём права на выполнение
4. запускаем ./daemon будучи в папке с файлом. Если ошибок нет, всё будет работать
5. А ещё скрипт можно установить как демон в systemd и управлять с помощью /etc/init.d/daemon.service (start|stop|restart) и есть ещё bash-скрипт который будет держать службу на контроле и перезапускать если что, так как не всегда ошибка возвращает код и systemd считает, что процесс не упал, а его остановили, но это уже другая история

6. Для решения задачи "Требуется по запросу юзера (нажал кнопку) вести отсчет таймера от 120 секунд до 0 и произвести действие" в php на действие пользователя просто запустить exec('/var/project/daemon', $output_1, $exitval);
Ответ написан
Пригласить эксперта
Ответы на вопрос 6
@Wexter
серверы очередей gearman/rabbitmq/...
Ответ написан
Комментировать
PQR
@PQR
Это можно сделать на ReactPHP, который по сути всегда запущен на сервере и работает в режиме event loop (как Node.js) https://reactphp.org/
Ответ написан
Комментировать
@BorisKorobkov Куратор тега PHP
Web developer
Можно вести обратный отсчет setTimeout на клиенте, по истечении времени - ajax запрос на сервер.

Если сразу на сервер, то должен быть какой-либо демон.
Ответ написан
Комментировать
@Redozator
На сервере debian/ubuntu я использую команду start-stop-daemon, чтобы запустить php-скрипт в фоновом режиме. Скрипт крутится постоянно. Время от времени, через крон, его можно убивать и запускать снова с целью избежать утечек памяти.
Ответ написан
Комментировать
dllweb
@dllweb
Автор, не заморачивайся, все просто, в начале файла скрипта:
set_time_limit(0);
ignore_user_abort(1);
Далее уже таймер и вся остальная логика, однако такой вариант не даёт 100% выполнения скрипта, а примерно 95% того что скрипт выполнит свою работу спустя отрезок времени
Ответ написан
Комментировать
Я делал похожую задачу на очередях, у rabbitmq есть плагин для отложенных сообщений, ты пуляешь ему сообщение (юзер 1 нажал кнопку) и говоришь, что бы оно было доставлено через 120 секунд и есть скрипт, который обрабатывает эти сообщения. rabbitmq не буду советую для простых задач, возможно есть что-то полегче
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
19 апр. 2024, в 23:00
5000 руб./за проект
19 апр. 2024, в 20:43
20000 руб./за проект