我想使用migrate
而不是控制台窗口up
down
/ code
数据库。我查看了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
。
答案 0 :(得分:2)
我可能会通过php函数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.
案例2
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.
答案 1 :(得分:1)
\Yii::$app->runAction('migrate', ['migrationPath' => '@yii/rbac/migrations/']);
答案 2 :(得分:0)
您可以创建控制台应用程序并加载控制台配置以运行迁移:
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模板的路径。
答案 3 :(得分:0)
对于这种情况,我使用此解决方案。我仅实现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];
}
答案 4 :(得分:0)
使用Yii2的高级模板-Web应用程序中的控制台应用程序共享主机 我已经通过一些调整成功应用了上面的代码。
带有子文件夹的单域multi / web,例如。 company1 / web
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,例如'/ company3 / web /'
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
`````