Niklesh Raut
Niklesh Raut

Reputation: 34914

How can I handle subdomains with one laravel installation

I am creating a laravel project for which I need one laravel installation and use its instance in sub-domain with separate database. And those separate database's info will not be in config/database.php. It will get from master database and then reconnected to the other database.

I didn't find any proper way to do this.

Do you have any idea on this ?

Thanks for your time.

Upvotes: 16

Views: 4392

Answers (7)

absolute
absolute

Reputation: 91

Just stumbled across this question, and IMHO sometimes the simplest suggestion is the easiest.

I just place a simple switch at the head of the /config/database.php file:

switch($_SERVER['HTTP_HOST'])
{
case 'dev.yoursite.com':
    $selectedDatabase = 'mysite_dev';
    break;
case 'yoursite.com':
default:
    $selectedDatabase = 'mysite_live';
    break;
}

Then simply use the variable within the returned config variable.

return [
    'connections' => 
        ['mysql' =>
             ['database' => $selectedDatabase,
              'username' => 'user_name',
              'password' => 'xxxxxxxxx',
             ],
        ]
    ];

I know its not the laravel way, but it'll get you out of a fix if you just want to open up a quick testing environment using the same PHP coding, but a test instance of your database.

Upvotes: 4

gmarintes
gmarintes

Reputation: 1308

Here's how I would approach this:

In your config/database.php:

<?php
function getDatabaseConnectionParameters() {
    $connectionParams = array();

    // add the default connection
    // this is your master database
    $connParams = array(
        'driver'    => 'mysql',
        'host'      => 'localhost',
        'database'  => 'master',
        'username'  => 'master_user',
        'password'  => 'master_password',
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
        'strict'    => false,
    );
    array_push($connectionParams, array('mysql' => $connParams);

    // TODO: connect to your master database using PDO/mysqli or anything else you know.
    // The point is: you can't use Laravel ORM just yet because you are currently setting up its configuration!
    // Get the list of subdomain connection parameters and array_push it to $connectionParams just like above.
    // Example:
    // array_push($connectionParams, array('subdomain' => $subdomainConnParams)

    return $connectionParams;
}

return array (
    'default' => 'mysql'

    ,'connections' => getDatabaseConnectionParameters()
)
?>

With this, subdomain specific models only need to specify $connection correctly. Example:

<?php
class YourModel extends Eloquent {
    protected $connection = 'subdomain';
}
?>

This way, your subdomain database configurations could be saved in your master database, while making your models simple and still Laravel-ful. Also, there is no nasty hacks that would make upgrading Laravel version hard.

Upvotes: 0

John Roca
John Roca

Reputation: 1234

You can set DB configuration by doing this:

$tenant = Tenant::whereSubDomain($subdomain)->first();  
Config::set('database.connections.mysql.database', $tenant->db_name);       
Config::set('database.connections.mysql.username',$tenant->db_username);
Config::set('database.connections.mysql.password',$tenant->db_password);

dd(\DB::connection('mysql'));

See this link Set up dynamic database connection on Multi tenant application for your reference.

Upvotes: 3

oseintow
oseintow

Reputation: 7381

Multi-tenancy is a tricky architecture that needs care to model. There are several ways to achieve this architecture. Some decide to use a single database whiles others prefer to use multiple database(that is in your case).

They both have their pros and cons that you need to consider. There are a lot of factors that need to be taken into consideration before you start modeling your application. eg Virtual host configuration for subdomains, Database migration(rollback all databases when the need be, etc.). I will suggest these two packages that can help you going and give you more insight on how to model your application to suite what you want.

https://github.com/orchestral/tenanti

https://github.com/hyn/multi-tenant

Upvotes: 6

Moppo
Moppo

Reputation: 19285

I would do that way:

  • Create one database per domain

  • Set up the available DB connections in laravel config/database.php :

'connections' => [

     'mysql_domain_1' => [
        'driver'    => 'mysql',
        /* other config values... */
    ],

    'mysql_domain_2' => [
        'driver'    => 'mysql',
        /* other config values... */
    ]
];
  • In the early fase of the request cycle (for example in a Middleware), get the sub-domain from the request, and set the current DB connection accordingly

    For example create a middleware and in the handle method:

public function handle($request, Closure $next)
{
    //check the request URL and get subdomain

    //get the db connection associated to the subdomain 

    //set the connection for this request
    Config::set('database.default', $dbConnection);
} 

Config::set('database.default', $dbConnection ); will set the db connection used by the whole application for the current request cycle

Upvotes: 4

Arvind
Arvind

Reputation: 857

If you want to handle this from database then check the host name from the http url and call the database connection from main table according to host name. e.g. (http://abc.maindomain.com, get the abc from url)

Upvotes: 4

noodles_ftw
noodles_ftw

Reputation: 1313

Laravel supports multiple Database connections. Firstly, define the connections in config/database.php:

<?php
return array(

    'default' => 'default_connection',

    'connections' => array(

        // domain.com
        'default_connection' => array(
            'driver'    => 'mysql',
            'host'      => 'localhost',
            'database'  => 'primary_database',
            'username'  => 'username',
            'password'  => 'password'
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ),

        // sub.domain.com
        'subdomain_connection' => array(
            'driver'    => 'mysql',
            'host'      => 'localhost',
            'database'  => 'secondary_database',
            'username'  => 'username',
            'password'  => 'password'
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
        ),
    ),
);

Now to specify which connection your models should use you can set the $connection property in your models:

<?php

class YourModel extends Eloquent {

    protected $connection = 'subdomain_connection';

}

You can set the value of $connection programatically.

Upvotes: 7

Related Questions