拉丁的传说
(我假设您使用的是 Symfony 4 或更高版本 - 但也应该在稍加修改的早期版本中工作)第 1 部分 - 从 php 加载容器参数像这样创建文件“config/my_config.php”:<?php$container->setParameter('my_param', 'something1');$elements = [];$elements[] = 'yolo1';$elements[] = 'yolo2';$container->setParameter('my_param_which_is_array', $elements);在您的 services.yaml 文件中,像这样导入“my_config.php”:imports: - { resource: my_config.php }清除缓存。检查这些参数是否已加载到容器中 - 例如通过运行以下命令:php bin/console debug:container --parameter=my_param ----------- ------------ Parameter Value ----------- ------------ my_param something1 ----------- ------------php bin/console debug:container --parameter=my_param_which_is_array ------------------------- ------------------- Parameter Value ------------------------- ------------------- my_param_which_is_array ["yolo1","yolo2"] ------------------------- -------------------如果上述步骤有效,那么您可以在应用程序中使用容器中的参数。重要警告:如果您将安全凭证存储在此类 php 文件(db 用户和密码等)中,请确保您没有将其与应用程序其余部分的代码一起添加到存储库中 - 因此将其添加到“.gitignore”中,类似于“ .env”被添加到那里。有关处理 symfony 参数的更多信息,请参阅https://symfony.com/doc/current/service_container/parameters.html(在代码片段上,单击“PHP”选项卡而不是“YAML”以查看 PHP 示例)第 2 部分 - 根据 url(host) 或 CLI 参数使用不同的数据库要动态选择数据库连接凭据,我们可以使用学说连接工厂。我们将'doctrine.dbal.connection_factory'使用修改后的版本装饰默认服务:创建新文件“src/Doctrine/MyConnectionFactory.php”:<?phpnamespace App\Doctrine;use Doctrine\Bundle\DoctrineBundle\ConnectionFactory;use Doctrine\Common\EventManager;use Doctrine\DBAL\Configuration;use Symfony\Component\Console\Input\ArgvInput;use Symfony\Component\HttpFoundation\Request;class MyConnectionFactory{ /** * @var array */ private $db_credentials_per_site; /** * @var ConnectionFactory */ private $originalConnectionFactory; public function __construct($db_credentials_per_site, ConnectionFactory $originalConnectionFactory) { $this->db_credentials_per_site = $db_credentials_per_site; $this->originalConnectionFactory = $originalConnectionFactory; } /** * Decorates following method: * @see \Doctrine\Bundle\DoctrineBundle\ConnectionFactory::createConnection */ public function createConnection(array $params, Configuration $config = null, EventManager $eventManager = null, array $mappingTypes = []) { $siteName = $this->getSiteNameFromRequestOrCommand(); if (!isset($this->db_credentials_per_site[$siteName])) { throw new \RuntimeException("MyConnectionFactory::createConnection - Unknown site name: {$siteName}"); } return $this->originalConnectionFactory->createConnection( [ 'url' => $this->db_credentials_per_site[$siteName]['url'], ], $config, $eventManager, $mappingTypes ); } /** * @return string */ private function getSiteNameFromRequestOrCommand() { // If we are inside CLI command then take site name from '--site' command option: if (isset($_SERVER['argv'])) { $input = new ArgvInput(); $siteName = $input->getParameterOption(['--site']); if (!$siteName) { throw new \RuntimeException("MyConnectionFactory::getSiteNameFromRequestOrCommand - You must provide option '--site=...'"); } return (string) $siteName; } // Otherwise determine site name by request host (domain): $request = Request::createFromGlobals(); $host = $request->getHost(); switch ($host) { case 'my-blue-site.local.dev2': return 'blue_site'; case 'redsite.local.com': return 'red_site'; } throw new \RuntimeException("MyConnectionFactory::getSiteNameFromRequestOrCommand - Unknown host: {$host}"); }}现在让我们在 services.yaml 中设置装饰:(您可以在此处阅读有关装饰服务的更多信息:https : //symfony.com/doc/current/service_container/service_decoration.html) App\Doctrine\MyConnectionFactory: decorates: doctrine.dbal.connection_factory arguments: $db_credentials_per_site: '%db_credentials_per_site%'并'db_credentials_per_site'在“config/my_config.php”中添加参数 - 如您所见,它被注入到MyConnectionFactory上面:$container->setParameter('db_credentials_per_site', [ 'blue_site' => [ 'url' => 'mysql://user1:pass1@127.0.0.1:3306/dbname-blue', ], 'red_site' => [ 'url' => 'mysql://user2:pass2@127.0.0.1:3306/dbname-red', ],]);我们还需要一件事来支持 CLI 命令中的此功能 - 我们需要'--site'为每个命令添加选项。如您所见,它正在被读取\App\Doctrine\MyConnectionFactory::getSiteNameFromRequestOrCommand。对于将使用数据库连接的所有命令,这将是强制性的:在 services.yaml 中: App\EventListener\SiteConsoleCommandListener: tags: - { name: kernel.event_listener, event: console.command, method: onKernelCommand, priority: 4096 }创建新文件“src/EventListener/SiteConsoleCommandListener.php”:<?phpnamespace App\EventListener;use Symfony\Component\Console\Event\ConsoleCommandEvent;use Symfony\Component\Console\Input\InputOption;class SiteConsoleCommandListener{ public function onKernelCommand(ConsoleCommandEvent $event) { // Add '--site' option to every command: $command = $event->getCommand(); $command->addOption('site', null, InputOption::VALUE_OPTIONAL); }}现在我们准备测试它是否有效:当你调用http://my-blue-site.local.dev2/something,则'blue_site'数据库credenatials将被使用。当你调用http://something.blabla.com/something,则'red_site'数据库credenatials将被使用。当您运行以下命令时,'blue_site'将使用数据库凭据:php bin/console app:my-command --site=blue_site当您运行以下命令时,'red_site'将使用数据库凭据:php bin/console app:my-command --site=red_site