Я пытаюсь написать контроллер cronjob, поэтому я могу вызвать один веб-сайт и выполнить все модули cronjob.php. Теперь моя проблема в том, как мне это сделать?
Будет ли это завиток, поэтому я также могу подсчитать ошибки и успехи?
[Обновить]
Наверное, я недостаточно объяснил это.
Я хочу сделать один файл, который я могу назвать как из http: // server / cronjob, а затем заставить его выполнить каждый /application/modules/*/controller/CronjobController.php или сделать другой способ сделать это, чтобы все cronjobs не находятся в одном месте, но там же находится модуль. Это дало бы мне преимущество: если модуль не существует, он не пытается запустить свой cronjob.
Теперь мой вопрос заключается в том, как выполнить все модули CronjobController или вы сделаете это совершенно по-другому, чтобы он все еще оставался модульным?
И я хочу уметь определять, сколько cronjobs побежало успешно и сколько не было
После некоторых исследований и много промедления я пришел к простому выводу, что ZF-ized cron-скрипт должен содержать все функциональные возможности вашего приложения zend framework – без всякого представления. Я достиг этого, создав новый файл cronjobfoo.php в каталоге приложения. Затем я взял минимальный минимум: -my front controller (index.php) -my bootstrap.php
Я вытащил все материалы для просмотра и сосредоточился на сохранении настроек среды, настройке db, автозагрузчике и настройке реестра. Мне пришлось потратить немного времени на исправление корневой переменной документа и удалить некоторые функции OO, скопированные из моего загрузочного файла.
После этого я просто закодировал. В моем случае он собирал и отправлял по электронной почте ночные отчеты. Было здорово использовать Zend_Mail. Когда я был уверен, что мой сценарий работает так, как я хотел, я просто добавил его кронтаб.
удачи!
Для Zend Framework я в настоящее время использую приведенный ниже код. Скрипт включает только файл портала index.php, где загружаются все пути, среда и другой код Zendy. Определяя константу в скрипте cron, мы отменяем последний шаг, на котором выполняется приложение.
Это означает, что приложение только настроено, даже не загружено. На этом этапе мы начинаем загружать необходимые ресурсы, и это
//public/index.php if(!defined('DONT_RUN_APP') || DONT_RUN_APP == false) { $application->bootstrap()->run(); } // application/../cron/cronjob.php define("DONT_RUN_APP",true); require(realpath('/srv/www/project/public/index.php')); $application->bootstrap('config'); $application->bootstrap('db'); //cron code follows
Я бы предупредил, чтобы ваши cronjobs были доступны для общественности, потому что они могли быть запущены вне их обычного времени и, в зависимости от того, что они делают, вызывают проблемы (я знаю, что это не то, что вы намереваетесь, но, поставив их в фактический контроллер, он станет доступен из браузера). Например, у меня есть один cron, который отправляет электронные письма. Я был бы постоянно спам, если бы кто-то нашел URL-адрес cron и только начал его ударять.
То, что я сделал, это создать папку cron, и там был создан heartbeat.php, который загружает Zend Framework (минус MVC) для меня. Он проверяет базу данных, в которой есть список всех установленных заданий cron, и, если настало время для их запуска, генерирует экземпляры класса задания cron и запускает его.
Задачи cron – это только дочерние классы из абстрактного класса cron, который имеет такие методы, как install (), run (), deactivate () и т. Д.
Чтобы уволить работу, у меня просто есть простая запись crontab, которая запускается каждые 5 минут, которая поражает heartbeat.php. До сих пор он работал замечательно на двух разных сайтах.
Кто-то упомянул эту запись в блоге пару дней назад по fw-general (список рассылки, который я рекомендую читать, когда вы используете Zend Framework).
Существует также предложение для Zend_Controller_Request_Cli , которое должно решить это раньше или позже.
У меня есть доступ к выделенному серверу, и изначально у меня была другая загрузка для заданий cron. Я в конце концов ненавидел эту идею, просто желая, чтобы я мог сделать это в рамках существующей установки MVC и не должен беспокоиться о перемещении вещей.
Я создал файл cron.sh, сохраненный в моем корне сайта (не публичный), и в нем я поставил ряд команд, которые я хотел бы запустить. Поскольку я хотел запускать сразу несколько команд, я написал PHP внутри своих контроллеров, как обычно, и добавил завитые вызовы к этим URL-адресам внутри cron.sh. например curl http://www.mysite.com/cron_controller/action
Затем на интерфейсе cron я запустил bash /path/to/cron.sh
.
Как указывали другие, ваши коронки могут быть уволены любым, кто угадывает URL-адрес, поэтому всегда есть оговорка. Вы можете найти решение этого по-разному.
Взгляните на zf-cli
:
Это хорошо обрабатывает все задания cron.
Почему бы просто не создать crontab.php, в том числе и не потребовать файл bootstrap index.php?
Учитывая, что bootstrap выполняет Zend_Loader::registerAutoload()
, вы можете начать работать непосредственно с модулями, например myModules_MyClass::doSomething();
Таким образом вы пропускаете контроллеры. Задача Контроллера – контролировать доступ через http. В этом случае вам не нужен подход к контроллеру, потому что вы получаете доступ локально.
http://framework.zend.com/wiki/display/ZFPROP/Zend_Scheduler+-+Matthew+Ratzloff?rootCommentId=1819 эта ссылка, которую я нашел в googleing, кажется, тоже интересна.
Его не тихий, что я ищу, но если я не могу найти то, что искал, я буду сам.
У вас есть доступ к файловой системе в каталоги модулей? Вы можете перебирать каталоги и определять, где доступен CronjobController.php. Затем вы можете использовать Zend_Http_Client
для доступа к контроллеру через HTTP или использовать такой подход, как Zend_Test_PHPUnit
: имитировать фактический процесс отправки на локальном компьютере.
Вы можете настроить таблицу базы данных для хранения ссылок на скрипты cronjob (в своих модулях), а затем использовать команду exec с возвращаемым значением при передаче / сбое.
Я распространил gregor ответ на этот пост . Вот что получилось:
//public/index.php // Run application, only if not started from command line (cli) if (php_sapi_name() != 'cli' || !empty($_SERVER['REMOTE_ADDR'])) { $application->run(); }
Спасибо, gregor!
Мое решение:
Открытый cron url (для завитки) не является проблемой, существует множество способов избежать злоупотреблений. Как сказано, проверка удаленного IP-адреса является самой простой.
Это мой способ запуска Cron Jobs с Zend Framework
В Bootstrap я буду поддерживать настройку среды, так как это минус MVC:
public static function setupEnvironment() { ... self::setupFrontController(); self::setupDatabase(); self::setupRoutes(); ... if (PHP_SAPI !== 'cli') { self::setupView(); self::setupDbCaches(); } ... }
Также в Bootstrap я буду изменять setupRoutes и добавить настраиваемый маршрут:
public function setupRoutes() { ... if (PHP_SAPI == 'cli') { self::$frontController->setRouter(new App_Router_Cli()); self::$frontController->setRequest(new Zend_Controller_Request_Http()); } }
App_Router_Cli – это новый тип маршрутизатора, который определяет параметры контроллера, действия и дополнительные параметры на основе этого типа запроса: script.php controller=mail action=send
. Я нашел этот новый маршрутизатор здесь: Настройка Cron с Zend Framework 1.11 :
class App_Router_Cli extends Zend_Controller_Router_Abstract { public function route (Zend_Controller_Request_Abstract $dispatcher) { $getopt = new Zend_Console_Getopt (array()); $arguments = $getopt->getRemainingArgs(); $controller = ""; $action = ""; $params = array(); if ($arguments) { foreach($arguments as $index => $command) { $details = explode("=", $command); if($details[0] == "controller") { $controller = $details[1]; } else if($details[0] == "action") { $action = $details[1]; } else { $params[$details[0]] = $details[1]; } } if($action == "" || $controller == "") { die("Missing Controller and Action Arguments == You should have: php script.php controller=[controllername] action=[action]"); } $dispatcher->setControllerName($controller); $dispatcher->setActionName($action); $dispatcher->setParams($params); return $dispatcher; } echo "Invalid command.\n", exit; echo "No command given.\n", exit; } public function assemble ($userParams, $name = null, $reset = false, $encode = true) { throw new Exception("Assemble isnt implemented ", print_r($userParams, true)); } }
В CronController я делаю простую проверку:
public function sendEmailCliAction() { if (PHP_SAPI != 'cli' || !empty($_SERVER['REMOTE_ADDR'])) { echo "Program cannot be run manually\n"; exit(1); } // Each email sent has its status set to 0;
Команда Crontab выполняет такую команду:
* * * * * php /var/www/projectname/public/index.php controller=name action=send-email-cli >> /var/www/projectname/application/data/logs/cron.log