开发者

Cron Jobs in a Zend Framework 1.8+ application?

I am using Zend Framework 1.9.6. I want to start using cron jobs. I am new to this 开发者_Python百科so I'm not quite sure how to do this.

I'm thinking it would be a good idea to store my crons in /myapp/scripts or /myapp/application/cronjobs. What do you think? (my application only has a default module)

Once I've decided on a place to store them, how would I go about creating a script? Let's say that I want to access a database, check for changes, and send an email as a report. I would need to use some Zend_Db components, and Zend_Mail components, as well as read the default config values. I guess I might even want to Bootstrap the application? But I won't need any views so I don't know if that would be the best idea. I don't know. What should I do, and how can I do it? Again, I am using version 1.9.6 and created my application with the Zend_Tool command-line script.

I think there's enough information online about how to add the cron job to the crontab file. (My web host also offers a tool to make this really easy, so I'm not so much interested in this part).

Have you done this in a 1.8+ application? Do you have an example script you could share?

Solution

Since posting this question, I have started a new job and become more comfortable working with Zend Framework. Here's what we've been doing at the company I now work for. I'm not saying this is a best practice, or ideal, but this information may be helpful to someone.

  • Create a top level bin directory to store all command line scripts.
  • Create a "CLI bootstrap" file that can be included in any command line scripts which will bootstrap the application so that you have easy access to your models just like you would if you were working with a controller.
  • All of our cron job scripts live in the bin directory so they are not publicly accessible. Also, since they are command line scripts, they do not make use of controllers or views. They are mostly simple little procedural scripts. Our cron jobs are managed manually, so we don't always remember which cron jobs we have scheduled to run.


I found it easiest to have the exact same configuration as my main site by having a function that created the application shared across all cronjobs and the site.

I did it this way as although there is probably quite a bit more overhead, it didn't matter as much (extra couple of milliseconds on a cronjob are nothing) and as the setup was exactly the same I never ran into any issues using shared code. For example, add database config is in exactly the same place, and if I added another namespace (as you can see I have done), I could do it globally.
The one thing that you could consider doing is using a different bootstrapper, which would reduce the cost as you don't bootstrap the views (which the cron jobs have no need for)

My setup function is (called by cronjobs and the main application):

function createApplication() {
    require_once 'Zend/Application.php';
    $application = new Zend_Application(
            APPLICATION_ENV,
            CONFIG_PATH . '/application.ini'
    );
    $application->bootstrap();

    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->registerNamespace('Search_');

    return $application;
}

So as mentioned, in my cronjobs, I don't call $application->run()

However, as mentioned, you could use diffrent bootstraps for the cronjobs to avoid setting up the views. Before $application->bootstrap() is called, you need to call $application->setBootstrap()

 /*
  * @param $path the path to Bootstrap.php, if not set it will default to the 
  *             application bootstrap
  * @return Zend_Application
  */
function createApplication($path = null) {
    require_once 'Zend/Application.php';
    $application = new Zend_Application(
            APPLICATION_ENV,
            CONFIG_PATH . '/application.ini'
    );

    if ( $path ){
        $application->setBootstrap($path);
    }
    $application->bootstrap();

    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->registerNamespace('Search_');

    return $application;
}


I have just started using cron jobs with ZF2 as well. In the past I would have created a folder below public_html and called the file ever so often using cpanel. Works fine this way and I could quite easily have a separate cron job app running on my server, but that defeats the object since I was positive ZF2 would have something to deal with a common requirement.

As it stands, they do and it is a very few lines of code to get working and the crons are not accessible in views.

Take five minutes to read up about console routing.

It is really simple to use. I created a Cron module:

Cron
    config
        module.config.php
    src
        Cron
            Controller
                IndexController.php
    autoload_classmap.php
    Module.php 

As you can see, no views have been included and are not required as we have opted to use a console route as you can see in the module below:

module.config.php

return array(
    // Placeholder for console routes
    'controllers' => array(
        'invokables' => array(
            'Cron\Controller\IndexController' => 'Cron\Controller\IndexController'
        ),
    ),
    'console' => array(
        'router' => array(
            'routes' => array(
                //CRON RESULTS SCRAPER
                'my-first-route' => array(
                    'type'    => 'simple',       // <- simple route is created by default, we can skip that
                    'options' => array(
                    'route'    => 'hello',
                    'defaults' => array(
                        'controller' => 'Cron\Controller\IndexController',
                        'action'     => 'index'
                        )
                    )
                )

            ),
        ),
    ),


);

IndexController file::

<?php
// Cron/src/Cron/Controller/IndexController.php
namespace Cron\Controller;

use Zend\Mvc\Controller\AbstractActionController;

class CronController extends AbstractActionController
{
    public function indexAction()
    {
        echo "hello";
        echo "\r\n";
    }
}

Remember to include the new module in your main config file otherwise it will not work!

The autoload_classmap.php and Module.php files are standard.

Now the part that is a bit vague in the Zend Manual is how to invoke this from the command line.

From the console navigate to trunk (or public_html) (the directory before public) and run:

path/to/trunk>php public/index.php hello

It will output:

hello
path/to/trunk>

If you want you can cut and paste the code from: http://collabedit.com/58v4v

If you have never used console to run a php file before essentially you need to start with "php" and then the "php file name". You can invoke any php file like this...

Good luck

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜