2008-09-27 3 views
20

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

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

[Update]

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

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

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

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

ответ

6

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

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

хрон рабочих мест только дочерние классы от абстрактного класса хрон, который имеет такие методы, как установить(), запустить(), деактивации() и т.д.

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

+0

Я был думая также о злоупотреблениях, но пришло к простому решению. Позволяя некоторым IP-адресам запускать cronjob (в моем случае только 127.0.0.1), я получаю необходимую мне безопасность. Глобальный класс cronjob - это интересная идея :) – Thomaschaaf 2008-09-27 14:23:01

2

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

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

+0

Мне тоже нравится это решение. См. Обновленную версию этого скрипта в моем блоге: http://webdevbyjoss.blogspot.com/2010/09/running-zend-framework-application-from.html – webdevbyjoss 2011-09-22 15:11:52

0

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

0

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

+0

Я ищу что-то, что работает на windows и linux без больших изменений, поэтому все должно быть в php – Thomaschaaf 2008-09-28 08:00:35

1

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

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

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

12

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

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

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

удачи!

9

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

Это означает, что приложение настроено, даже не загружено. На данный момент мы начинаем bootstraping ресурсы, которые нам нужны, и в том, что

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

Я передал gregor ответ this post. Это то, что вышло:

//public/index.php 

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

Thanks gregor!

0

Мое решение:

  • локон/хрон
  • метод Global хрон будет include_once все контроллеры
  • Проверьте, имеет ли каждый из controllors -> метод хрон
  • Если у них есть, запустить их.

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

2

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

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

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

0

Это мой способ запуска 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. Я нашел этот новый маршрутизатор здесь: Setting up Cron with 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 
Смежные вопросы