Утилита для запуска PHP-скриптов в фоновом режиме

в 14:39, , рубрики: php, многозадачность, метки: ,

Предисловие

Возможно, вы думаете, что это — очередная статья о том, как расплодить процессы с помощью fork() через консоль PHP. Но увы, ни консоли, ни pcntl_fork() здесь не будет — только браузер и сервер с PHP.

Эту утилиту (назовем ее так) я писал на скорую руку (заранее извиняюсь за названия переменных), для своих нужд, а все потому, что не нашел ничего похожего.
Смысл этой утилиты все тот же — запустить скрипт, который будет сутки напролет работать в фоновом режиме (как вариант). Естественно, что можно сделать это и без всяких там утилит, но в таком случае мы поскользнемся сразу несколько раз подряд (многие эти места знают, но все же, повторюсь):

  • Некоторые браузеры похоронят наш скрипт через 30 секунд
  • Мы понятия не имеем, работает наш скрипт или нет
  • Результат работы скрипта будет отображен только на той странице, на которой мы его вызвали, так что остается только ждать окончания выполнения скрипта, не закрывая вкладки в браузере
  • Если скрипт делает что-то не так, но все же продолжает работать, мы об этом сразу и не узнаем

Есть еще множество минусов подхода «в один файл», но статья не о том.

Описание утилиты

Почему не использована консоль, pcntl_fork()

Когда писал утилиту, рассчитывал на то, что приидется использовать на разных серверах и в разных условиях, в которых не всегда можно воспользоваться консолью (платный / бесплатный хостинг) и в условиях, когда PHP используют как модуль Apache (в таком случае про pcntl_fork() можно забыть).

Принцип действия

Скрипт создается / редактируется в браузере

В случае, если нужно работать с телефона / планшета, или нет FTP-доступа к серверу. Использован замечательный редактор ace (ajax.org).

Запуск скрипта

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

Ход работы скрипта

Мы можем видеть все сообщения, которые выводит скрипт, в реальном времени.
Для вывода сообщений в консоль (импровизированную, в окне браузера), скрипт должен вызвать функцию

$PDT->display("Сообщение", "Тип");

После этого браузер получает сообщение об изменениях в файле консоли и обновляет консоль в браузере, уже с нашим сообщением (механизм долго объяснять, если кому-то интересно — могу написать по этой теме статью).

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

$PDT->running();

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

Если скрипт рассчитан на «прослушку» чего-то (бесконечный цикл, пока что-то не поменяется), и в нем не установлены задержки, то он сразу же загрузит процессор по завязку. Во избежание сего предусмотрена функция

$PDT->wait(1000);

которая добавляет паузу в милисекундах (ms, в данном примере равно 1 секунде) и устанавливает статус процеса «спящим / ожидающим».

Два скрипта (и больше), работающих паралельно, могут обмениваться данными между собой. Для обмена данными использованы файлы.
К примеру, первый скрипт (first) вызвал функцию

$PDT->write('Переменная', 'Значение');

а второй скрипт (second), который прослушивал «память» первого скрипта, заметил изменения

$var = $PDT->read('first.Переменная');

и изменил что-то

$PDT->write('first.Переменная', 'Другое значение');

(этот пример есть в скриптах на GitHub)

Данные в скрипт можно передать через консоль. В таком случае скрипт должен прослушивать ввод

$input = $PDT->input();

Примечание

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

Ссылка на утилиту (GitHub):
github.com/prineside/PDT

Достаточно скинуть все содержимое в одну папку и зайти в нее через браузер.

Автор: prineside

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js