|
|
|
| Задача не техническая, а скорее логическая =)
Пишу планировщик, пытаю его уже не один час.
Нужен запуск функции (рассылка сообщений) в определенное время. Раньше я обходился так, выбирал из базы рассылки те, у которых последняя рассылка была больше суток назад, если таких рассылок нет - выход. (sendtime - метка времени):
SELECT id FROM senders
WHERE sendtime < ". (time() - 60*60*24) ."
ORDER BY RAND()
LIMIT 1
Но нужно что-то большее, где бы была возможность настроить конкретное время.
За основу взял cron. То есть конструкцию вроде */2 * * * * (каждые 2 минуты)
и запрос сменяется на (в данном случае)
SELECT id FROM senders
WHERE sendtime + ". (60*2) ." < ". (time() ."
ORDER BY RAND()
LIMIT 1
при * */2 * * * (каждые 2 часа) строчка уже смениться на
WHERE sendtime + ". (60*60*2) ." < ". (time() ."
Но как быть, если указано */2 2 * * * (если не ошибаюсь, каждую минуту в течении 2го часа ночи)
Или * * * */1 (как я понял - каждый понедельник)
То есть, кто знает, как вообще организовать парсинг такой команды крона? | |
|
|
|
|
|
|
|
для: Artem S.
(23.04.2005 в 12:17)
| | В первую очередь необходимо разбить строку explode по пробелам, если она занимает один символ - это точное время, если при этом строка равна * - любое, если символа три следует выдирать последнюю цифру - получается периодичность. | |
|
|
|
|
|
|
|
для: cheops
(23.04.2005 в 20:57)
| | Я и сам до этого додумался. Проблема была, как это все прикрутить, чтоб получить работающий самопальный cron, запускаемый "нормальным" cron'om( =))) ) Идея была в том, чтоб не лезть каждый раз в админку к хостеру и не менять вручную.
Сделал так. Функция выдает в виде массива все метки времени, переданные в команде, при сравнении текущего времени и времени последнего запуска, находим "активные" задания, и выполняем их.
Если кому надо:
Понимает запись вида 30 12 1-15 1,3,5 (12:30 с 1 по 15 число янв, мар, мая)
<?
function cron_time($command)
{
$command = explode(" ", $command);
for($i = 0; $i < 4; $i++)
{
if( strpos($command[$i], "-") !== false )
{
if( !preg_match("/([0-9]{1,2})-([0-9]{1,2})/i", $command[$i], $matches) )
return false;
if( $matches[1] > $matches[2])
return false;
$command[$i] = null;
for($j = $matches[1]; $j < ($matches[2]+1); $j++)
$command[$i] .= empty($command[$i]) ? $j : ",". $j;
}
}
$month = explode(",", $command[3]);
$day = explode(",", $command[2]);
$hour = explode(",", $command[1]);
$minute = explode(",", $command[0]);
foreach($month as $m)
foreach($day as $d)
foreach($hour as $h)
foreach($minute as $min)
$cron[] = mktime($h, $min, 0, $m, $d, date("Y", time()));
return $cron;
}
?>
|
Может, кто лучше способ знает? | |
|
|
|