45

ブラウザのクエリまたはコントローラーからSymfony2コマンドを実行するにはどうすればよいのでしょうか。

それを実行するためにホスティングする可能性がなく、すべてのcronジョブが管理者によって設定されているためです。

機能を有効にしていないexec()ので、テストしたいときは、コマンドからテストコントローラーにすべてのコンテンツをコピーする必要がありますが、これは最善の解決策ではありません。

4

9 に答える 9

66

Symfony の新しいバージョンについては、この問題に関する公式ドキュメントを参照してください


runコントローラーからコマンドを実行するためのサービスは必要ありません。コンソール文字列入力ではなく、メソッドを介してコマンドを呼び出す方が良いと思いますが、公式ドキュメントでは、エイリアスを介してコマンドを呼び出すことをお勧めします。また、この回答を参照してください。Symfony 2.1-2.6 でテスト済み。

コマンドクラスは拡張する必要があります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);
    }
}

ほとんどの場合、BufferedOutput( Jbm の回答から) 必要なく、それを確認するだけで十分$resultCode is 0です。それ以外の場合はエラーが発生しました。

于 2013-08-07T11:29:43.653 に答える
57

コマンドをサービスとして登録し、呼び出すことを忘れないでくださいsetContainer

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

コントローラーでは、このサービスを取得し、権限の引数を指定して execute メソッドを呼び出すだけです。

setArgumentメソッドで入力を設定します。

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

runコマンドのメソッドを呼び出します。

$command = $this->get('MyCommandService');
$command->run($input, $output);
于 2012-05-08T12:58:19.010 に答える
10

私の環境( Symony 2.1 )では、 @Reuven ソリューションを機能させるためにいくつかの変更を加える必要がありました。どうぞ:

サービス定義 - 変更なし。

コントローラーで:

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);
}
于 2012-12-13T09:38:54.407 に答える
3

コンソールで行うのと同じようにコマンドを文字列として実行できる別の方法を次に示します (これを使用してサービスを定義する必要はありません)。

このバンドルのコントローラーをチェックして、すべての詳細がどのように行われるかを確認できます。ここでは、特定の詳細を省略して要約します (環境の処理など、ここではすべてのコマンドが呼び出されたのと同じ環境で実行されます)。

ブラウザからコマンドを実行するだけなら、そのバンドルをそのまま使用できますが、任意のコントローラーからコマンドを実行する場合は、次のようにします。

コントローラーで、次のような関数を定義します。

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;
}

次に、次のようなアクションから呼び出すことができます。

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

    return new Response($output);
}

また、フレームワークによって提供されるものがないため、出力バッファーとして機能するクラスを定義する必要があります。

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;
    }
}
于 2013-03-29T21:45:10.920 に答える
2

@malloc と同じですが、

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);
}
于 2013-12-18T23:23:48.447 に答える
0

このバンドルを使用して、コントローラー (http 要求) から Symfony2 コマンドを実行し、URL でオプション/パラメーターを渡すことができます。

https://github.com/mrafalko/CommandRunnerBundle

于 2014-04-30T20:11:41.443 に答える
0

env次のようなオプションが必要なコマンドを実行するとassetic:dump

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

を作成し、Symfony\Component\Console\Application次のように定義を設定する必要があります。

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);

envコマンドの定義にないため、オプションをコマンドに設定できません。

于 2015-04-16T15:15:03.093 に答える