Managing Console scripts with Silex

I’ve wrote about using the ConsoleServiceProvider with Silex a few months ago and after a few hours of programming, I had a lot of scripts which needed to run continuously. When debugging I needed to kill and restart those fairly quick. I’ve created a console script with a few helper classes to make my set up more manageable. I’ve added all these files to my silex-base repo. you can find everything in the readme.md file on how to use this.

When you want to create a script it works like this: First you create your own script in app/console. Make sure this file has all the right permissions. The next step is to add this to the config in the Console.php file. You can add a description, name & an interval. The default is an interval of 60 seconds. Next step is to create your own Command file. This file has to implement two methods: Configure (where you will fetch the config from the Console class) and execute (where you will execute your own code – see using the ConsoleServiceProvider with Silex a few months ago). I’ve also added a Timing class which calculates how long a script runs.

Console Scripts Config

When this is all configured, running the “app/console/console scripts” command will try to execute all scripts that are available.
You can kill those scripts with the –kill optional argument. You can start (or kill) a single script like this:

app/console/console scripts import (--kill)

The output of all those scripts can be found in the app/logs/console files.

Example

Advertisements

Using ConsoleServiceProvider with Silex

I recently needed a few scripts that run as cronjobs. Symfony has something like the Console Component which gives the possibility to create command line interfaces for your code.

The people from KNPLabs created a ConsoleServiceProvider which Provides a Symfony\Component\Console based console for Silex. Registering this service provider is easy as registering any other service provider. First step is adding the knplabs/console-service-provider to the composer.json file and running composer update.

{
   "require": {
      ...
      "knplabs/console-service-provider": "dev-master"
   },
   "autoload": {
      "psr-0": {"": "src/"}
   }
}

Next we’ll register the service and set some options:

use Knp\Provider\ConsoleServiceProvider;

/**
* Console Service Provider
*
*/
$app->register(new ConsoleServiceProvider(), array(
	'console.name' => 'ConsoleApp',
	'console.version' => '1.0.0',
	'console.project_directory' => __DIR__ . '/..'
));

Next up we’ll have to create a command script which extends the Knp\Command\Command. You’ll have to implement two methods to configure and execute a command. The configure method just defines what kind of commands are available and what kind of options you can use.

protected function configure() {
   $this
      ->setName('import')
      ->setDescription('Import all data.')
      ->addArgument(
         'userId',
         InputArgument::OPTIONAL,
         'Import for a specific user'
      )
      ->addOption(
         'debug',
         null,
         InputOption::VALUE_NONE,
         'If set, the task will run in debug mode'
      )
   ; // nice, new line
 }

If you need the Silex\Application $app you can retrieve it using the getSilexApplication() function (available in the Knp\Command\Command namespace).

Next we need a console script which will use the Command created earlier. This will look something like this:
import console

Tip: If the executing fails, try php -d display_errors script.php to check syntax mistakes.

The execute commands looks like this:

protected function execute(InputInterface $input, OutputInterface $output) {
// use $input->getArgument('userId'); and $input->getOption('debug')
}

This is actually all you need to do. The configuration in your ImportCommand file will basically tell your console how to use it. Running [path to console file] without arguments will give you output about how to use your options and commands. (ex. app/console/imports).

Output when running the console file without arguments
Output when running the console file without arguments

Wow! Now you can while(true) or for(;;) the shit out of your application!