я бы хотел 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
,
Я, вероятно, сделал бы это через функцию 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.
\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];
}