You can dynamically adjust the table names ( and mappings ) by hooking into the doctrine event-system with listeners/subscribers.
i.e. "loadClassMetadata" is one of doctrine's events you can create a listener/subscriber for as described in the cookbook article How to Register Event Listeners and Subscribers.
Example
config.yml
services:
mapping.listener:
class: AcmeYourBundleEventListenerMappingListener
tags:
- { name: doctrine.event_listener, event: loadClassMetadata }
MappingListener
use DoctrineORMEventLoadClassMetadataEventArgs;
class MappingListener
{
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
$classMetadata = $eventArgs->getClassMetadata();
$table = $classMetadata->table;
$oldName = $table['name']; // ... or $classMetaData->getTableName()
// your logic here ...
$table['name'] = 'new_table_name';
$classMetadata->setPrimaryTable($table);
// ... or add a field-mapping like this
$fieldMapping = array(
'fieldName' => 'about',
'type' => 'string',
'length' => 255
);
$classMetadata->mapField($fieldMapping);
ClassMetadata extends ClassMetadataInfo and provides a public variable "table" ( containing the mapping information provided by your annotations or yml ) which you can modify !
The public table variable is an array with the following entries:
- name =>
- schema =>
- indexes => array
- uniqueConstraints => array
You can dynamically register event-listeners/subscribers in your controller prior to saving/updating.
$mappingListener = new MappingListener();
// ... maybe even modify the listener using reflection
$evm = $this->get('doctrine')->getManager()->->getEventManager();
$evm->addEventListener('loadClassMetadata', $mappingListener);
Furthermore you can introduce multiple database connections/names and access them in your application.
app/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
customer:
driver: "%database_driver2%"
host: "%database_host2%"
port: "%database_port2%"
dbname: "%database_name2%"
user: "%database_user2%"
password: "%database_password2%"
charset: UTF8
Then get different entity managers using ...
$em = $this->get('doctrine')->getManager('default');
$em2 = $this->get('doctrine')->getManager('customer');
or repositories
$customers = $this->get('doctrine')
->getRepository('AcmeCustomerBundle:Customer', 'customer')
->findAll()
;
... or add connections dynamically
$this->get('doctrine')
->connection('mysql://username:password@localhost/test', 'dynamic_connection');
Read more about the topic in the cookbook chapter How to work with Multiple Entity Managers and Connections.