Создать cronjob с Zend Framework - PullRequest
       34

Создать cronjob с Zend Framework

21 голосов
/ 27 сентября 2008

Я пытаюсь написать контроллер cronjob, чтобы я мог вызвать один веб-сайт и выполнить все модули cronjob.php. Теперь моя проблема в том, как мне это сделать?

Будет ли опция curl, чтобы я также мог посчитать ошибки и успехи?

[Update]

Полагаю, я недостаточно объяснил.

То, что я хочу сделать, - это иметь один файл, который я могу вызвать как http://server/cronjob, а затем заставить его выполнять каждый /application/modules/*/controller/CronjobController.php или иметь другой способ сделать это так все cronjobs не в одном месте, а в одном и том же месте, где находится модуль. Это дает мне преимущество в том, что если модуль не существует, он не пытается запустить свой cronjob.

Теперь мой вопрос: как бы вы выполнили все модули CronjobController или сделали бы это совершенно по-другому, чтобы он по-прежнему оставался модульным?

И я хочу быть в состоянии выдать, сколько cronjobs успешно запустилось, а сколько нет

Ответы [ 14 ]

12 голосов
/ 16 июля 2009

После некоторого исследования и большого промедления я пришел к простому выводу, что скрипт cron на языке ZF-ized должен содержать все функциональные возможности вашего приложения на основе Zend Framework - без всего, что нужно для просмотра. Я достиг этого, создав новый файл cronjobfoo.php в моей директории приложения. Тогда я взял минимум из: Мой фронт-контроллер (index.php) -my bootstrap.php

Я убрал все элементы просмотра и сосредоточился на сохранении настроек среды, настроек БД, автозагрузчика и настроек реестра. Мне потребовалось немного времени, чтобы исправить корневую переменную документа и удалить некоторые функции OO, скопированные с моего загрузчика.

После этого я просто закодировал ... в моем случае он собирал и отправлял ночные отчеты по электронной почте. Было здорово использовать Zend_Mail. Когда я был уверен, что мой скрипт работает так, как я хотел, я просто добавил его в свой crontab.

удачи!

9 голосов
/ 13 августа 2009

Для 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
6 голосов
/ 27 сентября 2008

Я бы предостерег, чтобы ваши cronjobs были доступны для публики, потому что они могут быть запущены вне их обычного времени и, в зависимости от того, что они делают, вызывают проблемы (я знаю, что это не то, что вы намереваетесь, но помещая их в реальный контроллер это становится доступным из браузера). Например, у меня есть один cron, который отправляет электронные письма. Я буду постоянно получать спам, если кто-то найдет URL-адрес cron и просто начнет его нажимать.

Я сделал папку cron и создал heartbeat.php, который загрузил мне Zend Framework (без MVC). Он проверяет базу данных, в которой есть список всех установленных заданий cron, и, если для них настало время, генерирует экземпляры класса задания cron и запускает его.

Задания cron - это просто дочерние классы из абстрактного класса cron, в котором есть такие методы, как install (), run (), deactivate () и т. Д.

Чтобы уволить меня с работы, у меня есть простая запись в crontab, которая запускается каждые 5 минут и которая переходит в heartbeat.php. Пока что он прекрасно работал на двух разных сайтах.

2 голосов
/ 11 ноября 2011

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

Я создал файл cron.sh, сохраненный в корне моего сайта (не общедоступный), и в него я поместил серию команд, которые я хотел бы запустить. Поскольку я хотел запускать много команд одновременно, я написал PHP в своих контроллерах, как обычно, и добавил вызовы curl для этих URL в cron.sh. например curl http://www.mysite.com/cron_controller/action Затем на интерфейсе cron я запустил bash /path/to/cron.sh.

Как указали другие, ваши кроны могут быть уволены любым, кто угадает URL, поэтому всегда есть такая оговорка. Вы можете найти решение этой проблемы разными способами.

2 голосов
/ 27 сентября 2008

Кто-то упомянул эту запись в блоге пару дней назад на fw-general ( список рассылки , который я рекомендую прочитать при использовании Zend Framework).

Существует также предложение для Zend_Controller_Request_Cli , которое должно решить эту проблему рано или поздно.

1 голос
/ 18 декабря 2010

Взгляните на zf-cli:

Хорошо справляется со всеми задачами cron.

1 голос
/ 09 апреля 2009

Почему бы просто не создать файл crontab.php, включая или требующий файл начальной загрузки index.php?

Учитывая, что загрузчик выполняет Zend_Loader::registerAutoload(), вы можете начать работать непосредственно с модулями, например, myModules_MyClass::doSomething();

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

0 голосов
/ 13 апреля 2019

Нет смысла запускать загрузчик в том же каталоге или в папке заданий cron. Я создал лучший и простой способ реализовать работу cron. Пожалуйста, следуйте приведенным ниже инструкциям, чтобы сделать вашу работу легкой и умной:

  1. Создайте папку заданий cron, такую ​​как "cron" или "crobjob" и т. Д., Что вы хотите.

  2. Иногда нам нужно, чтобы задание cron запускалось на сервере с другим интервалом, например, с интервалом в 1 час или 1 день, который мы можем настроить на сервере.

  3. Создайте файл в папке заданий cron, как я создал файл init.php. Теперь предположим, что вы хотите отправлять пользователям новостную рассылку один раз в день. Вам не нужно делать зенд-код в init.php.

  4. Так что просто установите функцию curl в init.php и добавьте URL вашего действия контроллера в эту функцию curl. Потому что наша главная цель состоит в том, чтобы акцию вызывали каждый день. например, URL должен быть таким:

https://www.example.com/cron/newsletters

Так что настройте этот URL в функции curl и вызовите эту функцию в файле init.php в том же файле.

В приведенной выше ссылке вы можете видеть, что "cron" - это контроллер, а рассылка - это действие, в котором вы можете выполнять свою работу, точно так же, не нужно запускать файл начальной загрузки и т. Д.

0 голосов
/ 27 июля 2012

Это мой способ запуска 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
0 голосов
/ 09 мая 2011

Мое решение:

  • curl / cron
  • Глобальный метод cron будет включать в себя все контроллеры
  • Проверьте, имеет ли каждый из контроллеров -> метод cron
  • Если они есть, запустите их.

Публичный cron url (для curl) не проблема, есть много способов избежать злоупотреблений. Как уже говорилось, проверка удаленного IP является самой простой.

...