Running console commands using Process component in Symfony 2

Hi All,

Today I am going to talk about process component in Symfony 2. Process component is a useful library which can be used to run console commands as it is. The main driving factor to discuss this topic is, recently I had an issue in running multiple console commands in Symfony 2. I tried using doRun method in Application. It worked for commands like doctrine:mapping:import and doctrine:generate:entities but not for doctrine:generate:form.  Even it worked for doctrine:generate:entities, I didn’t managed to generate a single entity in a bundle. I had to generate all entities for the whole bundle. In other words “php app/console doctrine:generate:entities ACMETestBundle:Person –no-backup” did not worked. So I had a really difficult time with this until someone suggested me about the process component when I posted this question in StackOverflow.. To be honest, I didn’t had the opportunity to explore process component thoroughly before that. But I found that process component is a really cool library which we can use to run console commands in Symfony 2. I thought it might be useful for someone who is trying to run console command using the application. If you have struggled running console commands using Application’s, run or doRun methods, this post is especially for you.

Before discussing the process component, let me illustrate how to run console commands in Symfony using Application’s doRun method.

public function executeBuildFormCommandActions($entity)
{
    $kernel = $this->container->get('kernel');        
    $kernel->shutdown();
    $kernel->boot();
    $app = new Application($kernel);       
    $app->setAutoExit(false);

    $input = new \Symfony\Component\Console\Input\ArrayInput(
            array('command' => 'doctrine:generate:entities', 'name' => 'TESTClientBundle',
        '--no-backup' => 'true'));
    $app->doRun($input, new \Symfony\Component\Console\Output\ConsoleOutput());
}

As you can see above I am trying to execute doctrine:generate:entities using this function. If you wonder how you run this command in console, this is how you call it.

php app/console doctrine:generate:entities TESTClientBundle –no-backup

This command will generate entity files for orm files under ClientBundle. I have used new Application instance which takes an instance of kernel. I had to shut down and boot the kernel (which I assume not a good approach) in order this to work. Because I wanted to run more than one console command one after other. Symfony didn’t let me generate entities without shutting down and booting the kernel when I run this command after running the doctrine:mapping:import command. Then you just run the command using doRun method by passing a ConsoleOutput object.

In process component, the way we call console commands is more like running a command in console (cmd). Now I will show you how to run doctrine:generate:form command using the process component. See the code snippet below,

public function executeBuildFormCommandActions($form_file)
{
    $move_to_project = 'C:/xampp5.5.11/htdocs/proj_test/';
    $commandline = "php app/console doctrine:generate:form TESTClientBundle:$form_file";
    $form_type_file = $this->get('kernel')->getRootDir() . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'TEST'
            . DIRECTORY_SEPARATOR . 'ClientBundle' . DIRECTORY_SEPARATOR .
            'Form' . DIRECTORY_SEPARATOR . $form_file.'Type.php';
    if(is_file($form_type_file)){
        unlink($form_type_file);
    }        

    $process = new \Symfony\Component\Process\Process($commandline);
    $process->setWorkingDirectory($move_to_project);
    $process->run();        
    try {
        if (!$process->isSuccessful()) {                
            throw new \RuntimeException($process->getErrorOutput());
        }            
        echo $process->getOutput().'<hr/>';
    } catch (\RuntimeException $r) {
        echo $r->getMessage();
    } 
}

Let me walk through about the above function. The function takes a parameter called $form_file. This parameter will be used to tell Symfony which entity’s form he should build. First what I do is, before creating the form file, I just check whether it already exists or not. If it does I am simply deleting it by calling php’s unlink method. Then I create a new Process instance by passing the command, which you need to run as you type in the console, which is this,

php app/console doctrine:generate:form TESTClientBundle:$form_file

As you can see I am passing what form to be generated using the function parameter. One thing you have to bare in your mind. Which is, you need to move to your current project directory, before executing any command. Otherwise process component cannot find app/console to run your command. It’s like you are executing the above command in C:\ drive. Which will not work because the app/console is inside your project directory. So you have to be inside the project directory. This can be done by using setWorkingDirectory() method. Currently I am passing a hard coded value, so make sure you pass path relative to your machine. Then, next, you simply run the command by calling the run method. You can surround this whole block by try-catch, which is always a good approach. Finally you can get the output by accessing the output method. This is relatively simple than using Application’s doRun method and sounds very logical to me. I hope you got an understanding how this process component works in terms of executing console commands.

I have tried this with these commands doctrine:mapping:import, doctrine:generate:entities and doctrine:generate:form. I hope this will work equally same way with rest of the commands.

Hope you enjoyed my post.

Cheers!

Share

One thought on “Running console commands using Process component in Symfony 2

  1. I read a lot of interesting content here. Probably you spend a lot of time writing, i know how to save you a lot of time, there
    is an online tool that creates readable, SEO friendly
    posts in seconds, just type in google – laranitas free content source

Leave a Reply to Todd Cancel reply

Your email address will not be published. Required fields are marked *