8

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!

1

3 Answers 3

8

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;
    }
}
?>
Sign up to request clarification or add additional context in comments.

Comments

3

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.

3 Comments

While I think a custom helper is one way to do this I am not sure if this is the right design decision - since it would be a helper which has functions that depends on certain models. I always had the feeling the helpers should be self-contained/independant.
It can be a component and depend on some classes, models, etc.
Calling one action from another is way worse for me.
0

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']);
}

2 Comments

He wants to call action of another controller.
Then it is good variant to 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']); } `

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.