Подтвердить что ты не робот

Создание cronjob с Zend Framework

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

Будет ли завиток быть вариантом, поэтому я также могу подсчитать ошибки и успехи?

[Обновление]

Думаю, я этого недостаточно объяснил.

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

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

И я хочу уметь определять, сколько cronjobs успешно прошло и сколько не

4b9b3361

Ответ 1

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

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

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

Удачи!

Ответ 2

Для Zend Framework я в настоящее время использую приведенный ниже код. script включает только файл портала index.php, где загружаются все пути, среда и другой код Zendy. Определив константу в cron script, мы отменим последний шаг, на котором выполняется приложение.

Это означает, что приложение только настроено, даже не загружено. На этом этапе мы начинаем загрузку необходимых ресурсов, а именно:

//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

Ответ 3

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

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

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

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

Ответ 4

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

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

Ответ 5

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

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

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

Ответ 6

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

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

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

Ответ 9

У вас есть доступ к файловой системе в каталоги модулей? Вы можете перебирать каталоги и определять, где доступен CronjobController.php. Затем вы можете использовать Zend_Http_Client для доступа к контроллеру через HTTP или использовать такой подход, как Zend_Test_PHPUnit: локализовать фактический процесс отправки.

Ответ 10

Вы можете настроить таблицу базы данных для хранения ссылок на сценарии cronjob (в своих модулях), а затем использовать команду exec с возвращаемым значением для pass/fail.

Ответ 11

Я добавил 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!

Ответ 12

Мое решение:

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

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

Ответ 13

Это мой способ запустить задания Cron с 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 скрипт.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

Ответ 14

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

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

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

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

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

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

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

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