[英]Yii2 Migrate Command Programmatically
我想使用code
而不是控制台窗口up
/ down
migrate
数据库。 我已经研究了framework
。 我尝试了以下代码:
$runner = new yii\console\Application([
'id' => 'auto-migrate',
'basePath' => dirname(__DIR__)
]);
$runner->runAction('migrate');
ob_start();
return htmlentities(ob_get_clean(), null, Yii::$app->charset);
它给出了Internal Server Error
。 而且甚至不将文件迁移到数据库。 但是,如果目录不存在,它将创建目录。 它的行为方式应该是这样,但是如果迁移文件存在于同一目录中,则会显示Internal Server Error
。
我可能会通过php function exec来做到这一点,但是如果您真的想通过创建新的应用程序实例来做到这一点,那么您应该能够做到这一点。
案例1-并非很好
//Define, if you want to capture output
defined('STDIN') or define('STDIN', fopen('php://input', 'r'));
defined('STDOUT') or define('STDOUT', fopen('php://output', 'w'));
//Create new console app, if you do not run it from root namespace you should use '\yii\console\Application'
$runner = new \yii\console\Application([
'id' => 'auto-migrate',
'controllerNamespace' => 'console\controllers', //for migrate command it should not matter but for other cases you must specify otherwise applocation cannot find your controllers
'basePath' => dirname(__DIR__ . '/../../console/config'), //This must point to your console config directory, when i run this in frontend sitecontroller i must add '/../../console/config',
'components' => [
'db' => [//If you want to call migrate you probably need some database component
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=mydb',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
],
]);
ob_start();
try
{
$runner->runAction('migrate/up');
}
catch(\Exception $ex)
{
echo $ex->getMessage();
}
return htmlentities(ob_get_clean(), null, Yii::$app->charset);
结果在我的情况下:
Yii Migration Tool (based on Yii v2.0.1) No new migration found. Your system is up-to-date.
情况二
ob_start();
try
{
$output = Array();
exec(__DIR__ . '/../../yii migrate/up', $output);
echo implode("\n", $output);
}
catch(\Exception $ex)
{
echo $ex->getMessage();
}
return htmlentities(ob_get_clean(), null, Yii::$app->charset);
结果在我的情况下:
Yii Migration Tool (based on Yii v2.0.1) No new migration found. Your system is up-to-date.
\Yii::$app->runAction('migrate', ['migrationPath' => '@yii/rbac/migrations/']);
您可以通过加载控制台配置来创建控制台应用程序以运行迁移:
public function actionMigrate()
{
// Keep current application
$oldApp = \Yii::$app;
// Load Console Application config
$config = require \Yii::getAlias('@app'). '/config/console.php';
new \yii\console\Application($config);
$result = \Yii::$app->runAction('migrate', ['migrationPath' => '@app/migrations/', 'interactive' => false]);
// Revert application
\Yii::$app = $oldApp;
return;
}
上面的示例代码用于yii2-app-basic模板,您可以更改yii2-app-advanced模板的路径。
对于这种情况,我使用此解决方案。 我仅实现migrate/up
案例。 要执行任何其他migrate
命令,必须配置runAction()
的参数。
use yii\console\controllers\MigrateController;
/*Suppose that config is an array with the following structure
[
'class' => 'yii\db\Connection',
'dsn' => "$dsn",
'username' => "$username",
'password' => "$password",
'charset' => 'utf8',
]
*/
public function migrateUp($config){
$migrate = new MigrateController('migrate', \Yii::$app);
/*The name of the table for keeping applied migration information*/
$migrate->migrationTable = 'migration';
/*At least one of `migrationPath` or `migrationNamespaces` should be specified.
For this example I use `migrationNamespaces` to find a specific set of migrations I want to execute.*/
$migrate->migrationNamespaces = [
'app\modules\v1\migrations'
];
$migrate->migrationPath = null;
/*The DB connection object to use when applying migrations*/
$migrate->db = $config;
/*Run migrations without asking questions*/
$migrate->interactive = false;
/*The individual commands ran within the migration will not be output to the console*/
$migrate->compact = true;
/*php://temp is a read-write stream that allow temporary data to be stored in a file-like wrapper */
define('STDOUT', $fp= fopen('php://temp', 'r+'));
/*run migrate/up */
$status = $migrate->runAction('up');
/*Rewind the position of the file pointer*/
rewind($fp);
$migrationOutput = stream_get_contents($fp);
if (isset($status)){
ob_get_clean();
return ['Errors when executing migrations', $migrationOutput];
}
return ['Everything ok', $migrationOutput];
}
在Web应用程序中使用Yii2的“高级模板-控制台”应用程序进行共享托管我已通过一些调整成功应用了上述代码。
单域multi / web及其子文件夹,例如。 公司1 /网络
multi/web/index.php
/.htaccess
/assets
/common/config/main.php
/common/config/bootstrap.php
/config/main-local.php has
/only db and urlManager baseUrl=''
/console/config/main.php
/frontend/config/main.php
/images
/company1/web/assets
/company1/web/images
/company1/web/.htaccess
/company1/web/index.php
/company1/config/main-local.php
/company2/web/assets
/company2/web/images
/company2/web/.htaccess
/company2/web/index.php
/company2/config/main-local.php
/company3/web/assets
/company3/web/images
/company3/web/.htaccess
/company3/web/index.php
/company3/config/main-local.php
/vendor
每个公司配置main-local仅包含db和UrlManager组件。 UrlManager的baseUrl,例如 '/公司3 /网络/'
multi / web index.php配置如下:
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
defined('YII_CONSOLE') or define('YII_CONSOLE', false);
//vendors from composer.json
require (__DIR__ . '/vendor/autoload.php');
//yii framework
require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php');
//common frontend bower and installer aliases
require(__DIR__ . '/common/config/bootstrap.php');
//empty
require(__DIR__ . '/frontend/config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
//vendor path, twilio, paypal
require(__DIR__ . '/common/config/main.php'),
//db=installer , urlmanager swiftmailer
require(__DIR__ . '/common/config/main-local.php'),
//etc... db and UrlManager Removed into above
require(__DIR__ . '/frontend/config/main.php'),
//cookie validation key
require(__DIR__ . '/frontend/config/main-local.php')
);
(new yii\web\Application($config))->run();
?>
每个公司的子文件夹的index.php配置如下:
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
defined('YII_CONSOLE') or define('YII_CONSOLE', false);
require(dirname(dirname(__DIR__)) . '/vendor/autoload.php');
require(dirname(dirname(__DIR__)) . '/vendor/yiisoft/yii2/Yii.php');
//aliases eg. common frontend bower
require(dirname(dirname(__DIR__)) . '/common/config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
//vendor path components ...rbac
require(dirname(dirname(__DIR__)) . '/common/config/main.php'),
//customer's database and urlmanager and swiftmailer taken out of frontend/config/main.php
require(dirname(__DIR__) . '/config/main-local.php'),
//excluding components db and urlmanager included in above
require(dirname(dirname(__DIR__)) . '/frontend/config/main.php'),
//cookie validation key
require(dirname(dirname(__DIR__)) . '/frontend/config/main-local.php')
);
//
(new yii\web\Application($config))->run();
``````
I have created an action in my Site controller to perform the console migration within the actionMigrateto_company_database.
<?php
public function actionMigrateto_company_database()
{
ob_start();
defined('STDIN') or define('STDIN', fopen('php://input', 'r'));
defined('STDOUT') or define('STDOUT', fopen('php://output', 'w'));
defined('STDERR') or define('STDERR', fopen('php://stderr', 'w'));
$oldApp = \Yii::$app;
// Load Console Application config
$config = yii\helpers\ArrayHelper::merge(
//migration namespaces and
//namespaces included in individual
//migration files
require \Yii::getAlias('@console'). '/config/main.php',
//vendor path components ...rbac
require \Yii::getAlias('@common').'/config/main.php',
//database
require (dirname(dirname(__DIR__)) .dirname(Yii::$app->urlManager->baseUrl). '/config/main-local.php'));
$runner = new \yii\console\Application($config);
$runner->runAction('migrate',['db','interactive' => 0]);
fclose(\STDOUT);
fclose(\STDIN);
fclose(\STDERR);
\Yii::$app = $oldApp;
return ob_get_clean();
}
?>
Adjust the frontend\views\layouts\main.php with
if (Yii::$app->UrlManager->baseUrl === '') and
if (Yii::$app->UrlManager->baseUrl <> '') statements.
.htaccess files are all as follows:
`````
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
`````
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.