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
精彩评论