I have created two different Yii2 console commands/controllers.
Example to call them is
# yii user/create-account
and
# yii webserver/update-config
After user/create-account has run I want to call webserver/update-config - is it possible doing this from within Yii by code? Or do I have to use exec()/system() to externally call the second yii php script (I would prefer not to).
Any help/insight would be appreciated!
After some consideration the way I chose to call one controller from within another was by using the runAction method of the controller (which is also the recommended way by the Yii developers).
Example for a console application:
\Yii::$app->runAction('webserver/update-config');
It is also possible to hand over params by using an array in as second parameter.
An example for simple parameters:
\Yii::$app->runAction('webserver/update-config', ['oneValue', 'anotherValue'];
Here an example for named parameters:
\Yii::$app->runAction('webserver/update-config', [
'servertype' => 'oneSetting',
'serverdir' => 'anotherSettingValue'
]);
Please note that this makes the called controller a part of the calling code. So if the called controller fails for some reason the whole program fails.
Good error handling is a must. In the called controller you can set the error code to give back by using return.
Example:
Calling line of code:
$iExitCode = \Yii::$app->runAction('webserver/update-config', ['oneValue', 'anotherValue'];
Called controller:
<?php
namespace app\commands;
use yii\console\Controller;
/**
* Webserver related functions
*/
class WebserverController extends Controller {
public function actionUpdateConfig($oneValue, $anotherValue) {
// Code that does something
if ($success) return 0;
else return 1;
}
}
?>
Calling one action from another (even inside one controller) is not very good practice and clear. I suggest another approach.
Move updating webserver config logic outside of a Webserver
controller, for example place it in some component / helper.
Then you can call this method from anywhere in particular in both user controller and webserver controller.
Example. In Webserver
component:
public static function updateConfig()
{
...
}
In User
controller:
public function actionCreateAccount()
{
...
Webserver::updateConfig();
}
In Webserver
controller:
public function actionUpdateConfig()
{
Webserver::updateConfig();
}
I think this is more reusable and clear.
Variant 1
You can run one action of controller from another action. For example,
public function actionCreateAccount() {
// something
}
public function actionUpdateConfig() {
// something
}
public function actionComplex() {
$this->actionCreateAccount();
$this->actionUpdateConfig();
}
Or
public function actionCreateAccount() {
// something
$this->actionUpdateConfig();
}
public function actionUpdateConfig() {
// something
}
Variant 2
If you neet to call action of another controller, you can use run() method of console controller:
For example, action in WebmasterController:
public function actionUpdateConfig($param1, $param2)
{
echo $param1 . '/' . $param2 . PHP_EOL;
}
action in UserController:
public function actionCreateAccount()
{
echo 'test: ';
$this->run('webmaster/update-config', ['do', 'it']);
}