How can I run symfony 2 run command from controller

前端 未结 9 1433
长发绾君心
长发绾君心 2020-11-28 20:03

I\'m wondering how can I run Symfony 2 command from browser query or from controller.

Its because I don\'t have any possibility on hosting to run it

相关标签:
9条回答
  • 2020-11-28 20:18

    If you run a command that need the env option like assetic:dump

    $stdout->writeln(sprintf('Dumping all <comment>%s</comment> assets.', $input->getOption('env')));
    

    You have to create a Symfony\Component\Console\Application and set the definition like that:

    use Symfony\Component\Console\Application;
    use Symfony\Component\Console\Input\ArgvInput;
    use Symfony\Component\Console\Input\InputDefinition;
    use Symfony\Component\Console\Input\InputOption;
    use Symfony\Component\Console\Output\NullOuput;
    
    // Create and run the command of assetic
    $app = new Application();
    $app->setDefinition(new InputDefinition([
        new InputOption('env', '', InputOption::VALUE_OPTIONAL, '', 'prod')
    ]));
    $app->add(new DumpCommand());
    
    /** @var DumpCommand $command */
    $command = $app->find('assetic:dump');
    $command->setContainer($this->container);
    $input = new ArgvInput([
        'command' => 'assetic:dump',
        'write_to' => $this->assetsDir
    ]);
    $output = new NullOutput();
    $command->run($input, $output);
    

    You can't set the option env to the command because it isn't in its definition.

    0 讨论(0)
  • 2020-11-28 20:21

    Here's an alternative that lets you execute commands as strings the same way you would on the console (there is no need for defining services with this one).

    You can check this bundle's controller to see how it's done with all the details. Here I'm going to summarize it ommiting certain details (such as handling the environment, so here all commands will run in the same environment they are invoked).

    If you want to just run commands from the browser, you can use that bundle as it is, but if you want to run commands from an arbitrary controller here is how to do it:

    In your controller define a function like this:

    use Symfony\Bundle\FrameworkBundle\Console\Application;
    use Symfony\Component\Console\Input\StringInput;
    
    private function execute($command)
    {
        $app = new Application($this->get('kernel'));
        $app->setAutoExit(false);
    
        $input = new StringInput($command);
        $output = new BufferedOutput();
    
        $error = $app->run($input, $output);
    
        if($error != 0)
            $msg = "Error: $error";
        else
            $msg = $output->getBuffer();
        return $msg;
    }
    

    Then you can invoke it from an action like this:

    public function dumpassetsAction()
    {
        $output = $this->execute('assetic:dump');
    
        return new Response($output);
    }
    

    Also, you need to define a class to act as output buffer, because there is none provided by the framework:

    use Symfony\Component\Console\Output\Output;
    
    class BufferedOutput extends Output
    {
        public function doWrite($message, $newline)
        {
            $this->buffer .= $message. ($newline? PHP_EOL: '');
        }
    
        public function getBuffer()
        {
            return $this->buffer;
        }
    }
    
    0 讨论(0)
  • 2020-11-28 20:23

    In my environment ( Symony 2.1 ) I had to do some modifications to @Reuven solution to make it work. Here they are:

    Service definition - no changes.

    In controller:

    use Symfony\Component\Console\Input\ArgvInput;
    use Symfony\Component\Console\Output\ConsoleOutput;
    
    ...
    
    public function myAction() {
        $command = $this->get('MyCommandService');
    
        $input = new ArgvInput(array('arg1'=> 'value'));
        $output = new ConsoleOutput();
    
        $command->run($input, $output);
    }
    
    0 讨论(0)
提交回复
热议问题