You may want to execute a script from the command line (or via a cron table) with access to all the symfony classes and features, for instance to launch batch e-mail jobs or to periodically update your model through a process-intensive calculation. The simple way of doing this is to create a PHP script that reproduces the first steps of a front controller, so that symfony is properly initialized. You can also use the symfony command line system, to take advantage of arguments parsing and automated database initialization.
16.3.1. Batch Files
Initializing symfony just takes a couple lines of PHP code. You can take advantage of all symfony features by creating a PHP file, for instance under the lib/
directory of your project, starting with the lines shown in Listing 16-13.
Listing 16-13 - Sample Batch Script, in lib/myScript.php
<?php
require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'dev', true);
sfContext::createInstance($configuration);
// Remove the following lines if you don't use the database layer
$databaseManager = new sfDatabaseManager($configuration);
$databaseManager->loadConfiguration();
// add code here
This strongly looks like the first lines of a front controller (see Chapter 6), because these lines do the same: initialize symfony, parse a project and an application configuration. Note that the ProjectConfiguration::getApplicationConfiguration
method expects three parameters:
- an application name
- an environment name
- a boolean, defining if the debug features should be enabled or not
To execute your code, just call the script from the command line:
> php lib/myScript.php
16.3.2. Custom tasks (new in symfony 1.1)
An alternative way of creating custom command line scripts using symfony is to write a symfony task. Just like the cache:clear
and the propel:build-model
tasks, you can launch your own custom tasks from the command line with php symfony
. Custom tasks benefit from the ability to parse command line arguments and options, can embed their own help text, and can extend existing tasks.
A custom task is just a class extending sfBaseTask
and located under a lib/task/
directory, either under the project root, or in a plugin directory. Its file name must end with 'Task.class.php'. Listing 16-14 shows a sample custom task.
Listing 16-14 - Sample Task, in lib/task/testHelloTask.class.php
class testHelloTask extends sfBaseTask
{
protected function configure()
{
$this->namespace = 'test';
$this->name = 'hello';
$this->briefDescription = 'Says hello';
}
protected function execute()
{
// your code here
$this->log('Hello, world!');
}
}
The code written in the execute
method has access to all the symfony libraries, just like in the previous batch script. The difference is how you call the custom task:
> php symfony test:hello
The task name comes from the protected namespace
and name
properties (not from the class name, nor from the files name). And since your task is integrated into the symfony command line, it appears in the task list when you just type:
> php symfony
Rather than writing a task skeleton by yourself, you can use the symfony generate:task
task. It creates an empty task, and has plenty of customization options. Make sure you check them by calling:
> php symfony help generate:task
Tasks can accept arguments (compulsory parameters, in a predefined order) and options (optional and unordered parameters). Listing 16-15 shows a more complete task, taking advantage of all these features.
Listing 16-15 - More Complete Sample Task, in lib/task/mySecondTask.class.php
class mySecondTask extends sfBaseTask
{
protected function configure()
{
$this->namespace = 'foo';
$this->name = 'mySecondTask';
$this->briefDescription = 'Does some neat things, with style';
$this->detailedDescription = <<<EOF
The [foo:mySecondTask|INFO] task manages the process of achieving things for you.
Call it with:
[php symfony foo:mySecondTask frontend|INFO]
You can enable verbose output by using the [verbose|COMMENT] option:
[php symfony foo:mySecondTask frontend — verbose=on|INFO]
EOF;
$this->addArgument('application', sfCommandArgument::REQUIRED, 'The application name');
$this->addOption('verbose', null, sfCommandOption::PARAMETER_REQUIRED, 'Enables verbose output', false);
}
protected function execute($arguments = array(), $options = array())
{
// add code here
}
}
Note If your task needs access to the database layer, it should extend sfPropelBaseTask
instead of sfBaseTask
. The task initialization will then take care of loading the additional Propel classes. You can start a database connection in the execute()
method by calling:
$databaseManager = new sfDatabaseManager($this->configuration);
If the task configuration defines an application
and an env
argument, they are automatically considered when building the task configuration, so that a task can use any of the database connections defined in your databases.yml
. By default, skeletons generated by a call to generate:task
include this initialization.
code.83d98555a5a990b9d25bec1f84d4559eebb33529yaml
Article: ## Insert records in the blog_article table
first_post: ## First record label
title: My first memories
content: |
For a long time I used to go to bed early. Sometimes, when I had put
out my candle, my eyes would close so quickly that I had not even time
to say "I'm going to sleep".
second_post: ## Second record label title: Things got worse content: | Sometimes he hoped that she would die, painlessly, in some accident, she who was out of doors in the streets, crossing busy thoroughfares, from morning to night. code.ea03a813c7146357f94cfed34023adf1de62e523cli
php symfony propel:data-load — env=prod frontend code.807165dac74d204cd494a252197ad3b0ff3280f8cli php symfony propel:data-load --append frontend code.41ab181bd8fb79a92deef8c3fc602b57452658edcli php symfony propel:data-load frontend --dir[]=data/myfixtures code.7a14cd9b83a1db15272a92ef7e067b3002540f44yaml Comment: first_comment: article_id: first_post author: Anonymous content: Your prose is too verbose. Write shorter sentences. code.19c32a4a2ee91fb62a1e6998a909097046af0fcdyaml Author: first_author: name: John Doe article_authors: [first_post, second_post] code.1f8565aac765ecc72500fe3aec615bfb902c09cb 100_article_import_data.yml 200_comment_import_data.yml 300_rating_import_data.yml code.bbb27c5d91343a42ef2aa400d1b187ae8bdf8205cli php symfony project:freeze symfony_data_dir code.cd87db6286e24df999ec03cc97d96927c7e17c22cli php symfony project:unfreeze code.2edf758a2c3ae21803456dfe717b2970f1c43962ini [symfony] name=myproject
[production] host=myapp.example.com port=22 user=myuser dir=/home/myaccount/myproject/ code.ec816b47ee9528974e35803ed16c038200f61589cli
php symfony project:deploy production code.555a8f47afcc9eb363370dc649761a1f00c77a51cli php symfony project:deploy production --go code.dc59ad963d811d5e9cced5e0ea8e10ee3e6f2f9bphp $ php /path/to/symfony/data/bin/check_configuration.php code.c038d4e3790cc811dc3c7c339b94e56f4728697d .svn /cache/* /log/* /stats/* /web/uploads/* /web/frontend_dev.php code.118d3e99a3bb5dc37385052dceade05f123a2a5acli php symfony cache:clear code.bba3cbd7097a5c023ed914dfb511cd1db905df71cli php symfony project:disable APPLICATION_NAME ENVIRONMENT_NAME code.662522acd916531e2b5b0500043d7d3395d3710ecli php symfony project:enable APPLICATION_NAME ENVIRONMENT_NAME code.6395e6c9940a77a8af5de73f425917ba8f7a92f8cli php symfony project:clear-controllers code.88f73d1bdf5b7c252e3fbbfcbf8bdb0a2512d6e0cli php symfony project:permissions ```