How to run console command in yii2 from web

2019-04-22 08:16发布

问题:

I have created a console command in console/controllers with SuggestionController .

If i run command like php yii suggestions, its working.

I want to know how to execute console command from web without any extensions of yii2.

回答1:

It can be done much simpler

$oldApp = \Yii::$app;
new \yii\console\Application([
    'id' => 'Command runner',
    'basePath' => '@app',
    'components' => [
        'db' => $oldApp->db,
    ],
);
\Yii::$app->runAction('migrate/up', ['migrationPath' => '@yii/rbac/migrations/', 'interactive' => false]);
\Yii:$app = $oldApp;

Github LINK



回答2:

This is way I found and used some time ago to run yii console controller/action (I used this for run migrations from web).

In your web controller action:

// default console commands outputs to STDOUT
// so this needs to be declared for wep app
if (! defined('STDOUT')) {
    define('STDOUT', fopen('/tmp/stdout', 'w'));
}

$consoleController = new \yii\console\controllers\SuggestionController;
$consoleController->runAction('your action eg. index');

/**
* open the STDOUT output file for reading
*
* @var $message collects the resulting messages of the migrate command to be displayed in a view
*/
$handle = fopen('/tmp/stdout', 'r');
$message = '';
while (($buffer = fgets($handle, 4096)) !== false) {
$message .= $buffer . "\n";
}
fclose($handle);

return $message;


回答3:

You can either exec() your command ´´´php yii suggestions´´´ but this may result in permission issues with the webserver user.

The better way is to use a ConsoleRunner extension, e.g. yii2-console-runner or yii2-console-runner-extension which do the job control job a little bit more sophisticated and more secure with popen().

Always be aware of code injections when executing exec() and the like!



回答4:

As of Yii2 - 2.0.11.2 advanced app -- this works

First let's make sure controller and namespace correct. In this case frontend app accessing console application import method()

In console\controllers\FhirController

Set the alias to be available in the console\config\main.php [OPTIONAL]

'aliases' => [
    '@common' => dirname(__DIR__),
    '@frontend' =>  dirname(dirname(__DIR__)) . '/frontend',
    '@backend' =>  dirname(dirname(__DIR__)) . '/backend',
    '@console' =>  dirname(dirname(__DIR__)) . '/console',
],

Finally from the frontend view, make the call like this: In this case, calling the controller route fhir then method import()

$consoleController = new console\controllers\FhirController('fhir', Yii::$app); 
$consoleController->runAction('import');


回答5:

On a site I'm overhauling, I have a need for a background task, that can be toggled via an action, which requires that I can also find its pid using ps. After much googling and almost as much swearing, I pieced together the solution.

# First change to (already-calculated) correct dir:
chdir($strPath);

# Now execute with nohup, directed to dev/null, and crucially with & at end, to run async:
$output = shell_exec("nohup php yii <console controller>/<action> > /dev/null &");

Yes, I understand that shell_exec should be used with extreme caution, thanks.



回答6:

I think this is the simplest solution:

$controller = new SuggestionController(Yii::$app->controller->id, Yii::$app);
$controller->actionSuggestions();