Create cronjob with Zend Framework

前端 未结 13 2118
广开言路
广开言路 2020-12-13 14:32

I am trying to write a cronjob controller, so I can call one website and have all modules cronjob.php executed. Now my problem is how do I do that?

Would curl be an

相关标签:
13条回答
  • 2020-12-13 15:05

    This is my way to run Cron Jobs with Zend Framework

    In Bootstrap I will keep environment setup as it is minus MVC:

    public static function setupEnvironment()
    {
         ...
         self::setupFrontController();
         self::setupDatabase();
         self::setupRoutes();
         ...
         if (PHP_SAPI !== 'cli') { 
              self::setupView();
              self::setupDbCaches();
         }
         ...
    }
    

    Also in Bootstrap, I will modify setupRoutes and add a custom route:

    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 is a new router type which determines the controller, action, and optional parameters based on this type of request: script.php controller=mail action=send. I found this new router here: 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));
        }
    }
    

    In CronController I do a simple check:

    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 runs a command of this kind:

        * * * * * php /var/www/projectname/public/index.php controller=name action=send-email-cli >> /var/www/projectname/application/data/logs/cron.log
    
    0 讨论(0)
  • 2020-12-13 15:06

    I extended gregor answer with this post. This is what came out:

    //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 讨论(0)
  • 2020-12-13 15:09

    I have access to a dedicated server and I initially had a different bootstrap for the cron jobs. I eventually hated the idea, just wishing I could do this within the existing MVC setup and not have to bother about moving things around.

    I created a file cron.sh, saved is within my site root (not public) and in it I put a series of commands I would like to run. As I wanted to run many commands at once I wrote the PHP within my controllers as usual and added curl calls to those urls within cron.sh. for example curl http://www.mysite.com/cron_controller/action Then on the cron interface I ran bash /path/to/cron.sh.

    As pointed out by others your crons can be fired by anyone who guesses the url so there's always that caveat. You can find a solution to that in many different ways.

    0 讨论(0)
  • 2020-12-13 15:13

    Someone mentioned this blog entry a couple days ago on fw-general (a mailinglist which I recommend reading when you use the Zend Framework).

    There is also a proposal for Zend_Controller_Request_Cli, which should address this sooner or later.

    0 讨论(0)
  • 2020-12-13 15:15

    It doesn't make sense to run the bootstrap in the same directory or in cron job folder. I've created a better and easy way to implement the cron job work. Please follow the below things to make your work easy and smart:

    1. Create a cron job folder such as "cron" or "crobjob" etc. whatever you want.

    2. Sometimes we need the cron job to run on a server with different interval like for 1 hr interval or 1-day interval that we can setup on the server.

    3. Create a file in cron job folder like I created an "init.php", Now let's say you want to send a newsletter to users in once per day. You don't need to do the zend code in init.php.

    4. So just set up the curl function in init.php and add the URL of your controller action in that curl function. Because our main purpose is that an action should be called on every day. for example, the URL should be like this:

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

    So set up this URL in curl function and call this function in init.php in the same file.

    In the above link, you can see "cron" is the controller and newsletters is the action where you can do your work, in the same way, don't need to run the bootstrap file etc.

    0 讨论(0)
  • 2020-12-13 15:16

    You could set up a database table to hold references to the cronjob scripts (in your modules), then use a exec command with a return value on pass/fail.

    0 讨论(0)
提交回复
热议问题