The definitive guide of Symfony 1.1

16.3. Using symfony outside of a web context

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 ```