• Добавить Cron средствами PHP

  •  

PHP замечательный язык. На него есть сотни расширений, но отсутствие некоторых из них иногда просто вымораживает. Сейчас я говорю о функционале, который позволил бы вызывать системный CRON средствами языка, не городя вокруг этого небезопасный и нарушающий все стандарты этики и работы с интерпретируемыми языками велосипед. О нем чуть дальше. Уже седьмая версия языка вышла, а встроенную функцию для вызова крона в пых так и не завезли. Язык, работающий по таймауту, язык, скрипты которого должны, просто обязаны завершаться, а не висеть в виде daemon’а, не имеет средств для вызова этих самых скриптов хотя-бы по плану, по Cron’у.

Это накладывает на разработчика определенные ограничения. Особенно на разработчика доргенов, вроде меня. Приходится ваять длиннопост прямо в интерфейсе приложения, в котором, в свою очередь, приходится объяснять пользователю, как установить отложенный постинг материалов в дорген так, чтобы он еще и работал. Плюс приходится встраивать AJAX Cron, тот-же велосипед, который срабатывает при посещении сайта пользователем.

Cron

Разумеется такой подход добавляет дискомфорта в привычную жизнь типичного форточника. Открывать консоль SSH никому не интересно. Пользователь воспринимает это как дополнительные трудности. Потому я решил упростить задачу, а за одно и разрешить данную проблему для других программистов. Раз уж вы читаете этот пост. И так. Какой же велосипед позволит добавить задачу CRON на PHP?

$cstring = "0 */3 * * * wget -qO --timeout=30 /dev/null ".get_site_url()."?vkcron=".$secret;

$otxt = print_r(shell_exec("crontab -l > mycron
#echo new cron into cron file
echo \"".$cstring."\" >> mycron
#install new cron file
crontab mycron
rm mycron"),true);

$l = print_r(shell_exec("crontab -l"),true);
die(json_encode(array("e"=>$otxt."\r\nГотово!", "l"=>$l)));

В данном случае используется вырезка кода из плагина WordPress, но, думаю, понять не составит особого труда. Обратите внимание на этот код:

shell_exec("crontab -l > mycron
#echo new cron into cron file
echo \"".$cstring."\" >> mycron
#install new cron file
crontab mycron
rm mycron")

Именно он отдает демону crontab команду на добавление задачи. Делается это следующим образом. В директории пользователя создается файл ‘mycron’ в который помещается строка с, собственно, задачей. Потом этот файл подсовывается crontab’у. Вот и все.

Работать, разумеется, данный код будет не у всех, а только у тех, кто не заблокировал опасную функцию ‘shell_exec’ на своем хостинге. Но, хоть даже для них, пусть будет больше комфорта в работе со скриптом. Так решил я.

Теперь вторая задача. Нам надо удалить таск из Crontab’а. Сделать это можно, выделив строку с задачей из списка и подсунув ее crontab’у.

$cstring = "wget -qO --timeout=30 /dev/null ".get_site_url()."?vkcron=".$secret;

$otxt = print_r(shell_exec("crontab -l | grep -v '".$cstring."' | crontab -"), true);

$l = print_r(shell_exec("crontab -l"),true);
die(json_encode(array("e"=>$otxt."\r\nГотово!", "l"=>$l)));

Обратите внимание на переменную $cstring в первом кодовом сегменте и в сегменте, приведенном выше. Как вы видите во втором случае у нас отсутствует строка ‘0 */3 * * *’, которая отвечает за время, в которое срабатывает задача. Проще говоря этот код позволяет удалить задачу по ее имени, вне зависимости от указанного в этой задаче времени.

Имеет ли право на жизнь такой подход к решению проблем пользователя? Да, имеет. Мы, программисты, следуем, в первую очередь, желаниям потребителя и порой так случается, что интересы безопасности и защищенности сервера пересекаются с интересами этого самого потребителя. Поэтому, пока в PHP отсутствует расширение с функционалом для планирования задач, этот путь имеет право на жизнь.

И еще: я требую лайка на stackoverflow!

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

ваш Гарри.

Гарри Поттер

 

P.S. на выходных встрою эту фичу в бесплатный RedOctober.

 13 комментариев
Страница 1 из 1
    heyzea1

    Почему пхпешники любят так извращаться и дергать крон через http, курлом и такой то матерью (а то и через ajax, это прям вообще до слез), а не напрямую через православный системный интерпретатор?

    По личному опыту разработчики на других ЯП так никогда не делают, только если недавно из php пришли.

    dorwaymoney

    А настроить CRON через панель?
    Или все крутые блоги на дешевы тарифа сидят?

    seoonly.ru

    Спасибо))

    Ginger Dog

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

    Spryt

    «дергать крон через http, курлом и такой то матерью» — потому что люди никогда не работают с командной строкой, и вообще не знают, что php скрипты исполняет интерпретатор, а не веб-сервер… Ну и разработка CLI-приложений требует определенных знаний, особенно с путями и правами на файлы (ибо запускается от лица юзера, а не веб-сервера). Поэтому такая еботня часто встречается в лоулевельных скриптах.

    Гарри, он вообще не про то, что ты через shell_exec ставишь задачу крону, а про то, что вместо «wget урл сайта» правильней делать «php /var/www/site.ru/update.php», что позволяет скрипту висеть в памяти хоть часами, парся всё нужное одни потоком (или кучей потоков, но ты до распараллеривания курла видимо тоже еще не дотянул).

Добавить Комментарий