I installed my static database to process login and rental information and an additional database to store user data.
application / Config / config.yml:
doctrine: dbal: default_connection: default connections: default: driver: "%database_driver%" host: "%database_host%" port: "%database_port%" dbname: "%database_name%" user: "%database_user%" password: "%database_password%" charset: UTF8 tenantdb: driver: "%database_driver%" host: "%database_host%" port: "%database_port%" dbname: "%database_name%" user: "%database_user%" password: "%database_password%" charset: UTF8 orm: default_entity_manager: default entity_managers: default: connection: default mappings: MyCoreBundle: ~ tenantdb: connection: tenantdb mappings: MyAppBundle: ~
And then in the controllers instead
$something = $this->getDoctrine() ->getManager() ->getRepository('MyAppBundle:Thing') ->findAll();
We have done:
$something = $this->getDoctrine() ->getManager('tenantdb') ->getRepository('MyAppBundle:Thing', 'tenantdb') ->findAll();
which you can find here: http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html
Then, based on Symfony2, Dynamic DB Connection / Early override of the Doctrine Service, I configured the service to switch databases based on the query subdomain (for example, tenant1.example.com tenant2.example.com)
SRC / MyCoreBundle / Resources / Config / services.yml:
services: my.database_switcher: class: MyCoreBundle\EventListener\DatabaseSwitcherEventListener arguments: [@request, @doctrine.dbal.tenantdb_connection] scope: request tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
MyCoreBundle \ EventListener \ DatabaseSwitcherEventListener.php
namespace MyCoreBundle\EventListener; use Symfony\Component\HttpFoundation\Request; use Doctrine\DBAL\Connection; class DatabaseSwitcherEventListener { private $request; private $connection; public function __construct(Request $request, Connection $connection) { $this->request = $request; $this->connection = $connection; } public function onKernelRequest() { $connection = $this->connection; if (! $connection->isConnected()) { $params = $this->connection->getParams(); $subdomain = __GET_SUBDOMAIN__(); $oldname = preg_replace ( "/_tenant_$subdomain|_template/", '', $params['dbname'] ); $params['dbname'] = $oldname . ($subdomain ? "_tenant_$subdomain" : "_template"); $connection->__construct( $params, $connection->getDriver(), $connection->getConfiguration(), $connection->getEventManager() ); $connection->connect(); } } }
For convenience, we have an "additional" tenant database called XXX_template, with which system administrators connect when global changes occur. It is planned that this database will be copied into the tenant's database on the creation of the tenant.