The definitive guide of Symfony 1.2

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.90487a2e67bcd5bc3999ac5e75b39767861e0b8fyaml 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.716c39cab4de722f2c21995016d4fbd61807092dcli

php symfony propel:data-load — env=prod frontend code.5aefab702723dd2f3dfe65f54ce8d915b15fb103cli php symfony propel:data-load --append frontend code.80f3207da1e99a9aa1b1c179db12fd1479f033b3cli php symfony propel:data-load frontend --dir[]=data/myfixtures code.a401302cd0d2be600412ff2498ffffd9692e3f2eyaml Comment: first_comment: article_id: first_post author: Anonymous content: Your prose is too verbose. Write shorter sentences. code.544d4a42c7285526f49f40a3e139e697655800f2yaml Author: first_author: name: John Doe article_authors: [first_post, second_post] code.1963f0cd10b7c76395055a1e39002763d935f54a 100_article_import_data.yml 200_comment_import_data.yml 300_rating_import_data.yml code.b76235513b6f8633a9c830745dc04945a08bb976cli php symfony project:freeze symfony_data_dir code.1b3e99267fdd49f39cecf82a7fbdb7687bcda3e6cli php symfony project:unfreeze code.3ec9b5e06a94aa7e66811c03affbdec61fc58ec2ini [symfony] name=myproject

[production] host=myapp.example.com port=22 user=myuser dir=/home/myaccount/myproject/ code.cc82f798b2d81fbb1a87fce98b34717d38c68863cli

php symfony project:deploy production code.7f4e8432c34242687be81707e27cb73e19cffe19cli php symfony project:deploy production --go code.c775f7fa0b4c422de7fb10c38bab3685d293cd34php $ php /path/to/symfony/data/bin/check_configuration.php code.c9b09be941127fe260ffcb03c5fb8c25161bcfb0 .svn /cache/* /log/* /stats/* /web/uploads/* /web/frontend_dev.php code.a0649ecc265d291a094fb83715813f417d2d32bbcli php symfony cache:clear code.7eeab4e4bf8cff842db825baa47853b6cbd9ceb9cli php symfony project:disable APPLICATION_NAME ENVIRONMENT_NAME code.710c126986b719e6f702affd80d9ecccd5245243cli php symfony project:enable APPLICATION_NAME ENVIRONMENT_NAME code.7a9409431e8e34774bde97433bf8154af1f6484fcli php symfony project:clear-controllers code.53bb4dab3325b59f84137ece646d07a1e317b554cli php symfony project:permissions ```