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

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

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

[Обновлять]

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

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

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

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


person Thomaschaaf    schedule 27.09.2008    source источник


Ответы (13)


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

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

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

удачи!

person ispytodd    schedule 16.07.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
person gregor    schedule 12.08.2009

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

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

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

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

person dragonmantank    schedule 27.09.2008
comment
Я тоже думал о злоупотреблениях, но пришел к простому решению. Разрешив только некоторым IP-адресам запускать cronjob (в моем случае только 127.0.0.1), я получаю необходимую мне безопасность .. Класс Global cronjob - интересная идея :) - person Thomaschaaf; 27.09.2008

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

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

person Till    schedule 27.09.2008
comment
Мне тоже нравится это решение. См. Обновленную версию этого скрипта в моем блоге: webdevbyjoss .blogspot.com / 2010/09 / - person webdevbyjoss; 22.09.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-адрес, поэтому всегда есть это предостережение. Вы можете найти решение этой проблемы разными способами.

person Gerald Ekosso    schedule 11.11.2011

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

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

person takeshin    schedule 18.12.2010

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

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

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

person Community    schedule 09.04.2009

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

person Stefan Gehrig    schedule 27.09.2008

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

person Bishop    schedule 28.09.2008
comment
Я ищу что-то, что работает в windows и linux без больших изменений, поэтому все должно быть на php - person Thomaschaaf; 28.09.2008

Я расширил ответ Грегора с помощью этот пост. Вот что получилось:

//public/index.php 

// Run application, only if not started from command line (cli)
if (php_sapi_name() != 'cli' || !empty($_SERVER['REMOTE_ADDR'])) {
    $application->run();
}

Спасибо, грегор!

person lony    schedule 13.01.2011

Мое решение:

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

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

person A.P.    schedule 09.05.2011

Это мой способ запускать задания 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 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
person Octavian Vladu    schedule 27.07.2012

Нет смысла запускать начальную загрузку в том же каталоге или в папке заданий 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» - это контроллер, а информационные бюллетени - это действие, в котором вы можете выполнять свою работу таким же образом, не нужно запускать файл начальной загрузки и т. Д.

person Shai tech    schedule 13.04.2019