Веб разработка →
Запланированная отправка постов (php, mongo, cron, regexp)
Добрый день.
Недавно мне пришлось писать страницу отправки постов на стены социальных сетей. Была поставлена задача постить на стену в определенное время а не сразу.
Я написал страницу с полями для выбора соц сетей, текстом сообщения и самим полем для ввода времени отправки. Кроме обычного календаря с выбором даты и времени отправки, я добавил еще одно поле с вводом критерия отправки по правилу cron.
Шаблон * * * * *
После этого встал вопрос — как получить только нужные поля для отправки?
Cron срабатывает каждую минуту и вызывает скрипт отправки постов, и перебирать каждую минуту всю таблицу подготовленных для отправки постов и сравниать с текущей датой/временем было бы лишней операцией.
Я использую базу данных MongoDB, которая может выбирать все поля по регулярному выражению. Вот что я сделал:
Берем текущую дату и время и переводим в массив
Далее строим регулярное выражение, которое выбирает записи, подходящие для отправки на текущий момент (текущая минута).
sendRule — название поля в базе, которое содержит наше cron правило.
$dateTime[0] (минуты) могут быть с нулями в начале (например 05 минут), по этому мы умножаем их на 1 что бы убрать ноль.
Тестировал * 1,12,20 7,8,12 * */3 (каждую минуту 1,12 и 20 часа 7,8,12 числа каждого месяца в среду).
Вот собственно и все, далее циклом обрабатываем полученный массив и отправляем все что нужно.
Недавно мне пришлось писать страницу отправки постов на стены социальных сетей. Была поставлена задача постить на стену в определенное время а не сразу.
Я написал страницу с полями для выбора соц сетей, текстом сообщения и самим полем для ввода времени отправки. Кроме обычного календаря с выбором даты и времени отправки, я добавил еще одно поле с вводом критерия отправки по правилу cron.
Шаблон * * * * *
После этого встал вопрос — как получить только нужные поля для отправки?
Cron срабатывает каждую минуту и вызывает скрипт отправки постов, и перебирать каждую минуту всю таблицу подготовленных для отправки постов и сравниать с текущей датой/временем было бы лишней операцией.
Я использую базу данных MongoDB, которая может выбирать все поля по регулярному выражению. Вот что я сделал:
Берем текущую дату и время и переводим в массив
$dateTime = explode(' ', date('i G j n w', time()));
Далее строим регулярное выражение, которое выбирает записи, подходящие для отправки на текущий момент (текущая минута).
$joe_search = new \MongoRegex(
'/^(\*|((\d{1,2}\,)|(\*\/))*('.($dateTime[0]*1).'){1}(\,\d{1,2})*)\s'.
'(\*|((\d{1,2}\,)|(\*\/))*('.($dateTime[1]).'){1}(\,\d{1,2})*)\s'.
'(\*|((\d{1,2}\,)|(\*\/))*('.($dateTime[2]).'){1}(\,\d{1,2})*)\s'.
'(\*|((\d{1,2}\,)|(\*\/))*('.($dateTime[3]).'){1}(\,\d{1,2})*)\s'.
'(\*|(([1-6]{1}\,)|(\*\/))*('.($dateTime[4]).'){1}(\,[1-6]{1})*)$/i'
));
$cursor = $collection->find(array("sendRule" => $joe_search));
sendRule — название поля в базе, которое содержит наше cron правило.
$dateTime[0] (минуты) могут быть с нулями в начале (например 05 минут), по этому мы умножаем их на 1 что бы убрать ноль.
Тестировал * 1,12,20 7,8,12 * */3 (каждую минуту 1,12 и 20 часа 7,8,12 числа каждого месяца в среду).
Вот собственно и все, далее циклом обрабатываем полученный массив и отправляем все что нужно.
07.03.2012 19:16+0400