run migrate command in a function in yii2

I want to write a function that run migrate command i write below code but it doesn’t work:


  

<?php

namespace app\controllers;


use Yii;

use yii\console\controllers;


class ModulesmigrationController extends \yii\web\Controller

 {

    public function actionRun()

      { 

     $migration = new Controllers\MigrateController;

     $migration->run('migrate', ['migrationPath' => '@app/myPath/']);

}


}



but i got this error:





  PHP Warning - yii\base\ErrorException

  Missing argument 1 for yii\base\Controller::__construct(), called in 

  C:\xampp\htdocs\... on line 12 and defined



please tell me,what should i do?

The error tells you what should be done:




$migration = new Controllers\MigrateController('migrate', Yii::$app);



when i did this




$migration = new Controllers\MigrateController('migrate', Yii::$app);

$migration->run('migrate', ['migrationPath' => '@app/mypath']);



i got this error


 Unable to resolve the request: migrate/migrate 

please ignore what i wrote . let me ask my question in another way.

How can i write a function that run migrate command ? should it be in controller or it should be a class or whatever?

1 Like

Did you find a solution to run the migrate command via function/controller?

I’m trying this

In frontend/controllers/SiteController i’ve added




public function actionMigrate()

    {

        // see http://www.yiiframework.com/forum/index.php/topic/60000-run-migrate-command-in-a-function-in-yii2/

        // and

        // http://www.yiiframework.com/wiki/667/yii-2-list-of-path-aliases-available-with-default-basic-and-advanced-app/

        $migration = new Controllers\MigrateController("migrate",Yii::$app);

        return $migration->run('migrate', ['migrationPath' => '@console/migrations/']);

    }



But I got a 404

If I simply




return "ok"



I see the ok, so is running the migrations the problem.

any idea?

I saw this: https://github.com/yiisoft/yii2/issues/1764#issuecomment-42436905

It’s of samdark

I fixed two typos and arrived to this (in frontend/controllers/siteController.php)




public function actionMigrateUp()

{

    // https://github.com/yiisoft/yii2/issues/1764#issuecomment-42436905

    $oldApp = \Yii::$app;

    new \yii\console\Application([

        'id'            => 'Command runner',

        'basePath'      => '@app',

        'components'    => [

            'db' => $oldApp->db,

        ],

    ]);

    \Yii::$app->runAction('migrate/up', ['migrationPath' => '@console/migrations/', 'interactive' => false]);

    \Yii::$app = $oldApp;

}



Still I got a 404

Tried changing




'basePath'      => '@console',



but no results… the same error… @samdark help !

tried also




'basePath'      => '@yii/console',



what am I doing wrong?

what’s the right method?

I found a workaround for my needs:




    public function actionMigrateUp()

    {

        //default console commands outputs to STDOUT so this needs to be declared for wep app

        if (!defined('STDOUT')) {

            define('STDOUT', fopen('/tmp/stdout', 'w'));

        }


        //migration command begin

        $migration = new \yii\console\controllers\MigrateController('migrate', Yii::$app);

        $migration->runAction('up', ['migrationPath' => '@console/migrations/', 'interactive' => false]);

        //migration command end


        /**

         * 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 . "<br>";

        }

        fclose($handle);


        return $this->render('index', ['message' => $message]);

    }



1 Like

Thanks a lot Emil, I’ll try ASAP.

@Emil: thanks, really, thanks a lot ! It’s very simple and it’s absolutely working.

I’d suggest to you to create a Wiki entry about this trick

Sorry for another reply, but I found a problem when moved from localhost development to remote testing environment.

Using your code, I changed the final ‘render’ with a redirect, as I setup the $message read from stdout file to be shown as a flash message.

Migration works, but they produce some output into webpage anyway, so redirect cannot work.

I got his output




> drop foreign key family_child_to_family_parent from table {{%family}} ... done (time: 0.011s) > drop table {{%family}} ... done (time: 0.004s) > drop table {{%auth_assignment}} ... done (time: 0.004s) > drop table {{%auth_item_child}} ... done (time: 0.003s) > drop table {{%auth_item}} ... done (time: 0.003s) > drop table {{%auth_rule}} ... done (time: 0.006s) > drop table {{%user}} ... done (time: 0.009s) > create table {{%user}} ... done (time: 0.005s) > create table {{%auth_rule}} ... done (time: 0.006s) > create table {{%auth_item}} ... done (time: 0.007s) > create index idx-auth_item-type on {{%auth_item}} (type) ... done (time: 0.048s) > create table {{%auth_item_child}} ... done (time: 0.004s) > create table {{%auth_assignment}} ... done (time: 0.004s) > create table {{%family}} ... done (time: 0.004s) > add foreign key family_child_to_family_parent: {{%family}} (parent_id) references {{%family}} (id) ... done (time: 0.008s) Ok



.

These are migrations details, but stdout is really capturing something because flash message, after manually change the page to the index, give me this




Yii Migration Tool (based on Yii v2.0.4)


Total 3 new migrations to be applied:

m130524_201442_init

m140506_102106_rbac_init

m150519_095654_create_family_table


*** applying m130524_201442_init

*** applied m130524_201442_init (time: 0.006s)


*** applying m140506_102106_rbac_init

*** applied m140506_102106_rbac_init (time: 0.070s)


*** applying m150519_095654_create_family_table

*** applied m150519_095654_create_family_table (time: 0.013s)




Migrated up successfully. 



Why redirecting of STDOUT works only partially ?

I repeat: migrations are working well, stdout redirect is working only partially, so I cannot do a redirect