我有一个关于与多个数据库相关的学说迁移的问题。根据这个问题和法师作为部署工具(但不仅限于法师,因为法师只自动执行手动操作):Symfony:可能加载不同的参数.yml?
当我走这条路时,在上面链接发布的问题中提到,我如何在每个数据库上进行迁移?因为在我看来,更改 AppKernel 加载器只能通过请求的 URL 进行,这对于学说迁移不存在,因为您在 shell 上运行它。
有人有提示吗,如何使用这种设置(一个应用程序源,每个多个参数的多个数据库),因为它不是我的选择,为此构建多个全栈 symfony 应用程序,因为一个安装超过 1GB应用程序之间的唯一区别是用户数据,我不想将其保存在一个数据库中,因为备份策略和其他策略(每个客户轻松备份,而不是使用 customerid 从一个数据库中提取)
希望我确实解释得足够清楚,我的问题是什么 - 并且更希望我确实设定了这个问题本身并且有人有解决方案;-)
更新和解决方案
我最终得到了一个可行的解决方案,大多数任务都是自动运行的。
首先,你必须在 SymfonyApp 中定义一个文件夹结构(我的在下面)
_portals
|-mySUBPORTAL
|-app
|-config
|-parameters.yml.prod
|-parameters.yml.stage
|-bin
|-var
|-cache
|-.gitkeep
|-logs
|-.gitkeep
|-sessions
|-.gitkeep
|-vendor
|-.gitkeep
|-web
|-.gitkeep
|-createAppStructure.php
文件 createAppStructure.php(如果需要,可以是可选的或定制的)
createAppStructure.php
#!/usr/bin/php
<?php
error_reporting(E_ERROR | E_WARNING | E_PARSE);
/** Parameter Check */
if(!array_key_exists(1,$argv)) exit('Es muss das Environment angegeben werden (stage|prod)'."\r\n");
/** Funktionen */
function getFolders($path)
{
$portalsDir = scandir($path);
$portals=[];
foreach($portalsDir as $portaldir)
{
if(!in_array($portaldir, [".",".."])) {
if(is_dir($path.DIRECTORY_SEPARATOR.$portaldir)) {
$portals[] = $path.DIRECTORY_SEPARATOR.$portaldir;
}
}
}
return $portals;
}
/** Alle Customers auslesen */
$env = $argv[1];
$basepath = dirname(__FILE__);
$portals = getFolders($basepath);
/** Alle Customers durchlaufen und Directory Struktur aufbauen */
$cmd = [];
$returnCode = 0;
foreach($portals as $customer)
{
$cmd=[];
/* Full Link Folders */
$cmd['fulllink'][] = "cd $customer";
$cmd['fulllink'][] = "ln -sf ../../src ./";
$cmd['fulllink'][] = "ln -sf ../../tests ./";
/* Root Struktur */
$cmd['rootDir'][] = "cd $customer";
$cmd['rootDir'][] = "ln -sf ../../composer.json ./";
$cmd['rootDir'][] = "ln -sf ../../composer.lock ./";
$cmd['rootDir'][] = "ln -sf ../../composer.phar ./";
/* App Struktur bauen */
$cmd['appDir'][] = "cd ".$customer.DIRECTORY_SEPARATOR."app/";
$cmd['appDir'][] = "ln -sf ../../../app/AppDoc ./";
$cmd['appDir'][] = "ln -sf ../../../../app/config/config.yml ./config/";
$cmd['appDir'][] = "ln -sf ../../../../app/config/config_prod.yml ./config/";
$cmd['appDir'][] = "ln -sf ../../../../app/config/config_dev.yml ./config/";
$cmd['appDir'][] = "ln -sf ../../../../app/config/config_test.yml ./config/";
$cmd['appDir'][] = "ln -sf ../../../../app/config/routing.yml ./config/";
$cmd['appDir'][] = "ln -sf ../../../../app/config/routing_dev.yml ./config/";
$cmd['appDir'][] = "ln -sf ../../../../app/config/parameters.yml.dist ./config/";
$cmd['appDir'][] = "ln -sf ../../../../app/config/security.yml ./config/";
$cmd['appDir'][] = "ln -sf ../../../../app/config/services.yml ./config/";
$cmd['appDir'][] = "ln -sf ../../../app/db ./";
$cmd['appDir'][] = "ln -sf ../../../app/DoctrineMigrations ./";
$cmd['appDir'][] = "ln -sf ../../../app/Resources ./";
$cmd['appDir'][] = "ln -sf ../../../app/.htaccess ./";
$cmd['appDir'][] = "cp -f ../../../app/AppCache.php ./";
$cmd['appDir'][] = "cp -f ../../../app/AppKernel.php ./";
$cmd['appDir'][] = "cp -f ../../../app/autoload.php ./";
$cmd['appDir'][] = "cp -f ./config/parameters.yml.".$env." ./config/parameters.yml";
/* Bin Struktur */
$cmd['binDir'][] = "cd ".$customer.DIRECTORY_SEPARATOR."bin/";
$cmd['binDir'][] = "cp -f ../../../bin/console ./";
$cmd['binDir'][] = "cp -f ../../../bin/symfony_requirements ./";
$cmd['binDir'][] = "ln -sf ../../../bin/wkhtmltox ./";
/* Var Struktur */
$cmd['varDir'][] = "cd ".$customer.DIRECTORY_SEPARATOR."var/";
$cmd['varDir'][] = "cp -f ../../../var/bootstrap.php.cache ./";
$cmd['varDir'][] = "cp -f ../../../var/SymfonyRequirements.php ./";
$cmd['varDir'][] = "ln -sf ../../../var/data ./";
/* Vendor Structure */
$cmd['vendorDir'][] = "cd $customer";
$vendorDirs = getFolders(dirname(__FILE__).DIRECTORY_SEPARATOR.'../vendor');
foreach($vendorDirs as $vendor) {
$vendorName = end(explode("/", $vendor));
if($vendorName!='composer') {
$cmd['vendorDir'][] = "ln -sf $vendor ./vendor/";
}
}
$cmd['vendorDir'][] = "cp -rpP ../../vendor/composer/ ./vendor/composer";
/* Web Struktur */
$cmd['webDir'][] = "cd ".$customer.DIRECTORY_SEPARATOR."web/";
$cmd['webDir'][] = "ln -sf ../../../web/bundles ./";
$cmd['webDir'][] = "ln -sf ../../../web/cache ./";
$cmd['webDir'][] = "ln -sf ../../../web/logos ./";
$cmd['webDir'][] = "cp -f ../../../web/.htaccess ./";
$cmd['webDir'][] = "cp -f ../../../web/app.php ./";
$cmd['webDir'][] = "cp -f ../../../web/app_dev.php ./";
$cmd['webDir'][] = "cp -f ../../../web/config.php ./";
$cmd['webDir'][] = "ln -sf ../../../web/apple-touch-icon.png ./";
$cmd['webDir'][] = "ln -sf ../../../web/favicon.ico ./";
$cmd['webDir'][] = "ln -sf ../../../web/robots.txt ./";
/* Administrative Tasks */
$cmd['administrative'][] = "cd $customer";
$cmd['administrative'][] = "./composer.phar install";
$cmd['administrative'][] = "bin/console --no-interaction doc:mig:mig";
$cmd['administrative'][] = "bin/console cache:clear --no-warmup";
$cmd['administrative'][] = "bin/console cache:warmup";
/** Run Commands */
$returnCode = 0;
$output = [];
foreach($cmd as $key => $command)
{
echo "Kommando wird ausgeführt => ".implode(" && ", $cmd[$key])." \r\n";
exec(implode(" && ", $cmd[$key]), $output, $retval);
echo "Rückgabecode: $retval"."\r\n";
$returnCode = ($retval==1) ? 1 : $returnCode ;
foreach($output as $line) {
echo "Output: $line"."\r\n";
}
}
}
exit($returnCode);
?>
您必须在每次部署应用程序后运行此脚本 - 我确实使用 mage (Magallanes) 来部署我的应用程序。所以我确实添加了一个任务(execShell)并用法师启动这个脚本。但您也可以手动运行它。
创建结构后,您可以访问 _portals/mySUBPortal/,您将找到一个具有所有功能的完整 symfony 应用程序结构。复制了某些类型的文件(否则,由于使用了DIR或FILE,它将无法正常工作),而其他类型的文件是符号链接的。
通过这种设置,您可以拥有相同的 SymfonyApp 源,但不同的数据库和工作学说迁移......
不要忘记将自定义 VHOST (APACHE/NGINX) 放在 DOCUMENT_ROOT 位于 _PORTALS 内的位置。