1

I have a simple Symfony2 app that needs to connect to a particular database based on the subdomain. Database names are the same as subdomain names.

Domain: alpha.example.com - DB name: alpha

Domain: beta.example.com - DB name: beta

The most simple way to achieve this, as I think of it, is to pass current subdomain into the config.yml file

#config.yml
doctrine:
    dbal:
        driver:   "%database_driver%"
        host:     "%database_host%"
        port:     "%database_port%"
        dbname:   "current-subdomain-name-here"
        user:     "%database_user%"
        password: "%database_password%"

The question is how to pass & access current subdomain name in config.yml?

Websirnik
  • 1,372
  • 3
  • 21
  • 35

4 Answers4

1

I don't think this is possible but in any case the configuration files shouldn't never contain any application logic.

You can follow the directives explained in the cookbook about multiple managers and connections and then create the logic (using the dependancy injection services for instance) but the implementation depends by your specific use case of which I don't know nothing.

gp_sflover
  • 3,460
  • 5
  • 38
  • 48
1

I'd avoid putting this into app.php. Maybe you need the same code also in app_dev.php for development and testing.

One config file per subdomain looks not very convenient too.

Take a look at:

http://symfony.com/doc/current/cookbook/configuration/external_parameters.html#miscellaneous-configuration

There you could do something like (not tested):

# app/config/config.yml
imports:
    - { resource: parameters.php }

-

// app/config/parameters.php
$subdomain = array_shift((explode(".",$_SERVER['HTTP_HOST'])));
$container->setParameter('doctrine.dbal.dbname', $subdomain);
Websirnik
  • 1,372
  • 3
  • 21
  • 35
Holger
  • 151
  • 3
0

You wouldn't want to do this in the config.yml. Rather, you should hook into the Kernel request and set your connection there. Check out the accepted answer to this post:

Symfony2, Dynamic DB Connection/Early override of Doctrine Service

You can then just use $this->request->getHost() in your listener, parse out the subdomain, and open a connection to your database after passing the subdomain's name as the dbname parameter. For example (not tested):

public function onKernelRequest()
{
    // this might cause issues if there is no subdomain, might need regex...just an example
    $dbname = array_shift(explode('.', $this->request->getHost()));
    $params = $this->connection->getParams();

    if ($dbname !== $params['dbname'])
    {
        $this->connection->close();

        $this->connection = new Connection()
            $params,
            $this->connection->getDriver(),
            $this->connection->getConfiguration(),
            $this->connection->getEventManager()
        );

        try {
            $this->connection->connect();
        } catch (Exception $e) {
            // log and handle exception
        }
    }
}
Community
  • 1
  • 1
Jason Roman
  • 8,146
  • 10
  • 35
  • 40
0

I've solved my own challenge in the following way.

I created different config files for each subdomain. In my case, I have a limited number of subdomains.

#config.yml
doctrine:
    dbal:
        driver:   "%database_driver%"
        host:     "%database_host%"
        port:     "%database_port%"
        user:     "%database_user%"
        password: "%database_password%"

Config for subdomain alpha.example.com:

#config_alpha.yml
doctrine:
    dbal:
        dbname:   "alpha"

Config for subdomain beta.example.com:

#config_beta.yml
doctrine:
    dbal:
        dbname:   "beta"

In the app.php we determine the subdomain, and load the corresponding config:

// web/app.php
// ...
$subdomain = array_shift((explode(".",$_SERVER['HTTP_HOST'])));
// In case of alpha.example.com
// $subdomain = "alpha"
// Its going to load config_alpha.yml
$kernel = new AppKernel($subdomain, true);
// ...
Websirnik
  • 1,372
  • 3
  • 21
  • 35