How can I run symfony 2 run command from controller

前端 未结 9 1432
长发绾君心
长发绾君心 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:03

    See official documentation on this issue for newer versions of Symfony


    You don't need services for command execution from controller and, I think, it is better to call command via run method and not via console string input, however official docs suggest you to call command via it's alias. Also, see this answer. Tested on Symfony 2.1-2.6.

    Your command class must extend ContainerAwareCommand

    // Your command
    
    use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
    
    class MyCommand extends ContainerAwareCommand {
        // …
    }
    
    
    // Your controller
    
    use Symfony\Component\Console\Input\ArrayInput;
    use Symfony\Component\Console\Output\NullOutput;
    
    class SomeController extends Controller {
    
        // …
    
        public function myAction()
        {
            $command = new MyCommand();
            $command->setContainer($this->container);
            $input = new ArrayInput(array('some-param' => 10, '--some-option' => true));
            $output = new NullOutput();
            $resultCode = $command->run($input, $output);
        }
    }
    

    In most cases you don't need BufferedOutput (from Jbm's answer) and it is enough to check that $resultCode is 0, otherwise there was an error.

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

    You can just simply create an instance of your command and run it:

    /**
     * @Route("/run-command")
     */
    public function someAction()
    {
        // Running the command
        $command = new YourCommand();
        $command->setContainer($this->container);
    
        $input = new ArrayInput(['--your_argument' => true]);
        $output = new ConsoleOutput();
    
        $command->run($input, $output);
    
        return new Response();
    }
    
    0 讨论(0)
  • 2020-11-28 20:13

    Register your command as a service and don't forget to call setContainer

    MyCommandService:
        class: MyBundle\Command\MyCommand
        calls:
            - [setContainer, ["@service_container"] ]
    

    In your controller, you'll just have to get this service, and call the execute method with the rights arguments

    Set the input with setArgument method:

    $input = new Symfony\Component\Console\Input\ArgvInput([]);
    $input->setArgument('arg1', 'value');
    $output = new Symfony\Component\Console\Output\ConsoleOutput();
    

    Call the run method of the command:

    $command = $this->get('MyCommandService');
    $command->run($input, $output);
    
    0 讨论(0)
  • 2020-11-28 20:16

    If you have to pass arguments (and/or options), then in v2.0.12 (and may be true for later versions), you need to specify InputDefinition first before instantiating an input object.

    use // you will need the following
        Symfony\Component\Console\Input\InputOption,
        Symfony\Component\Console\Input\InputArgument,
        Symfony\Component\Console\Input\InputDefinition,
        Symfony\Component\Console\Input\ArgvInput,
        Symfony\Component\Console\Output\NullOutput;
    
    
    // tell symfony what to expect in the input
    $inputDefinition = new InputDefinition(array(
        new InputArgument('myArg1', InputArgument::REQUIRED),
        new InputArgument('myArg2', InputArgument::REQUIRED),
        new InputOption('debug', '0', InputOption::VALUE_OPTIONAL),
    ));
    
    
    // then pass the values for arguments to constructor, however make sure 
    // first param is dummy value (there is an array_shift() in ArgvInput's constructor)
    $input = new ArgvInput(
                            array(
                                    'dummySoInputValidates' => 'dummy', 
                                    'myArg2' => 'myValue1', 
                                    'myArg2' => 'myValue2'), 
                            $inputDefinition);
    $output = new NullOutput();
    



    As a side note, if you are using if you are using getContainer() in your command, then the following function may be handy for your command.php:

    /**
     * Inject a dependency injection container, this is used when using the 
     * command as a service
     * 
     */
    function setContainer(\Symfony\Component\DependencyInjection\ContainerInterface $container = null)
    {
        $this->container = $container;
    }
    
    /**
     * Since we are using command as a service, getContainer() is not available
     * hence we need to pass the container (via services.yml) and use this function to switch
     * between conatiners..
     *
     */
    public function getcontainer()
    {
        if (is_object($this->container))
            return $this->container;
    
        return parent::getcontainer();
    }
    
    0 讨论(0)
  • 2020-11-28 20:17

    You can use this bundle to run Symfony2 commands from controller (http request) and pass options/parameters in URL.

    https://github.com/mrafalko/CommandRunnerBundle

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

    same as @malloc but

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