开发Symfony 3应用程序,我需要根据URL拥有一个多网站。 这是我的parameters.yml文件:
...
dbname_cda: my-website-cda
dbname_pts: my-website-pts
dbname_vis: my-website-vis
...
这是config.yml
doctrine:
dbal:
default_connection: my-website
connections:
my-website:
driver: pdo_mysql
host: "%dbhost%"
port: "%dbport%"
dbname: "%_______%"
user: "%dbuser%"
password: "%dbpassword%"
charset: UTF8
https://my-website.com/cda
会注入参数dbname_cda
。
https://my-website.com/pts
会注入参数dbname_pts
。
https://my-website.com/vis
会注入参数dbname_vis
。
实际上,除了根据网址从不同数据库加载数据外,它是同一个网站。
感谢您的帮助。
答案 0 :(得分:1)
这是一种解决问题的方法,考虑到您无法动态注入变量这一事实,因为这些配置变量是在Symfony&#34;编译时&#34;。< / p>
首先在app/config/config.yml
中声明您的所有连接(我只接受您的cda
和pts
连接):
doctrine:
dbal:
default_connection: cda
connections:
cda:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_cda_name%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
pts:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_pts_name%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: cda
entity_managers:
cda:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: cda
mappings:
AppBundle: ~
pts:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: pts
mappings:
AppBundle: ~
然后,在doctrine
中声明您自己的app/config/services.yml
服务版本。该版本将取代Symfony定义的版本。
services:
# ...
doctrine_url_switcher:
class: AppBundle\Doctrine\Registry
decorates: doctrine
arguments:
- '@doctrine_url_switcher.inner' # Original Doctrine service
- '@request_stack'
public: false
我在这里使用Symfony的service decoration机制来定义doctrine
服务的新版本。
现在,定义AppBundle\Doctrine\Registry
类,它扩展了Symfony的类,并在请求默认实体管理器或连接时使用RequestStack
:
<?php
namespace AppBundle\Doctrine;
use Doctrine\Bundle\DoctrineBundle\Registry as BaseRegistry;
use Symfony\Component\HttpFoundation\RequestStack;
class Registry extends BaseRegistry
{
private $requestStack;
public function __construct(BaseRegistry $baseRegistry, RequestStack $requestStack)
{
parent::__construct(
$baseRegistry->container,
$baseRegistry->getConnectionNames(),
$baseRegistry->getManagerNames(),
$baseRegistry->getDefaultConnectionName(),
$baseRegistry->getDefaultManagerName()
);
$this->requestStack = $requestStack;
}
/**
* {@inheritdoc}
*/
public function getConnection($name = null)
{
$connection = null;
$request = $this->requestStack->getCurrentRequest();
if ($request) {
$path = $request->getPathInfo();
if (preg_match(':^/cda:', $path)) {
$connection = 'cda';
} elseif (preg_match(':^/pts:', $path)) {
$connection = 'pts';
}
}
return parent::getConnection($connection);
}
/**
* {@inheritdoc}
*/
public function getManager($name = null)
{
$manager = null;
$request = $this->requestStack->getCurrentRequest();
if ($request) {
$path = $request->getPathInfo();
if (preg_match(':^/cda:', $path)) {
$manager = 'cda';
} elseif (preg_match(':^/pts:', $path)) {
$manager = 'pts';
}
}
return parent::getManager($manager);
}
}
通过重写Registry
类的方法,我们使用请求对象来确定应该使用哪个实体管理器或哪个连接。使用特定实体管理器名称或连接名称调用父方法,具体取决于URL。如果URL无法帮助找到要使用的URL,则使用默认值(在config.yml
中定义)。