【问题标题】:How can I handle subdomains with one laravel installation如何通过一个 laravel 安装处理子域
【发布时间】:2016-03-22 10:41:26
【问题描述】:

我正在创建一个 laravel 项目,我需要一个 laravel 安装,并在具有独立数据库的子域中使用它的实例。并且那些单独的数据库的信息不会在 config/database.php 中。它将从主数据库获取,然后重新连接到另一个数据库。

我没有找到任何合适的方法来做到这一点。

你对此有什么想法吗?

感谢您的宝贵时间。

【问题讨论】:

  • 您是在问如何设置子域?比如,对于两个独立的 Laravel 应用程序?
  • @CaptainHypertext 我认为子域部分将通过虚拟主机完成,我正在寻找处理数据库的建议。
  • 单独的数据库是否在同一台服务器上?
  • 是的,它们在同一个服务器上

标签: php laravel laravel-5 subdomain laravel-5.1


【解决方案1】:

Laravel 支持多个数据库连接。首先,在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'    => '',
        ),
    ),
);

现在要指定模型应该使用哪个连接,您可以在模型中设置 $connection 属性:

<?php

class YourModel extends Eloquent {

    protected $connection = 'subdomain_connection';

}

您可以通过编程方式设置$connection 的值。

【讨论】:

    【解决方案2】:

    多租户是一个需要小心建模的棘手架构。有几种方法可以实现这种架构。有些人决定使用单个数据库,而另一些人更喜欢使用多个数据库(在您的情况下)。

    它们都有你需要考虑的优点和缺点。在开始对应用程序建模之前,需要考虑很多因素。例如子域的虚拟主机配置,数据库迁移(需要时回滚所有数据库等)。我将推荐这两个包,它们可以帮助您前进,并让您更深入地了解如何为您的应用程序建模以适应您的需求。

    https://github.com/orchestral/tenanti

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

    【讨论】:

      【解决方案3】:

      如果您想从数据库中处理此问题,请检查 http url 中的主机名,并根据主机名从主表调用数据库连接。例如(http://abc.maindomain.com, 从 url 获取 abc)

      【讨论】:

        【解决方案4】:

        我会这样做:

        • 为每个域创建一个数据库

        • 在 laravel config/database.php 中设置可用的 DB 连接:

        'connections' => [
        
             'mysql_domain_1' => [
                'driver'    => 'mysql',
                /* other config values... */
            ],
        
            'mysql_domain_2' => [
                'driver'    => 'mysql',
                /* other config values... */
            ]
        ];
        
        • 在请求周期的早期(例如在中间件中),从请求中获取子域,并相应地设置当前的数据库连接

          例如创建一个中间件并在handle方法中:

        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 );将设置整个应用程序在当前请求周期使用的db连接

        【讨论】:

          【解决方案5】:

          您可以通过以下方式设置数据库配置:

          $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'));
          

          请参阅此链接Set up dynamic database connection on Multi tenant application 供您参考。

          【讨论】:

            【解决方案6】:

            偶然发现了这个问题,恕我直言,有时最简单的建议是最简单的。

            我只是在 /config/database.php 文件的头部放置了一个简单的开关:

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

            然后简单地使用返回的配置变量中的变量。

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

            我知道这不是 laravel 的方式,但如果你只想使用相同的 PHP 编码打开一个快速测试环境,但它是你的数据库的测试实例,它会让你摆脱修复。

            【讨论】:

              【解决方案7】:

              以下是我的处理方法:

              在你的 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()
              )
              ?>
              

              有了这个,子域特定模型只需要正确指定$connection。 示例:

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

              这样,您的子域数据库配置可以保存在您的主数据库中,同时使您的模型简单并且仍然是 Laravel-ful。 此外,没有令人讨厌的 hack 会使升级 Laravel 版本变得困难。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2014-08-03
                • 1970-01-01
                • 2018-02-02
                • 1970-01-01
                • 2015-01-14
                • 1970-01-01
                • 2015-12-17
                相关资源
                最近更新 更多