How can I handle subdomains with one laravel installation

时光毁灭记忆、已成空白 提交于 2019-11-30 05:07:10

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.

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

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

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)

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.

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!