Php Laravel 5.3-如何跨多个数据库执行查询?

Php Laravel 5.3-如何跨多个数据库执行查询?,php,mysql,laravel,laravel-5,Php,Mysql,Laravel,Laravel 5,我们目前有多个数据库,物理上位于不同的位置。它们的结构完全相同。由于某些法律法规的原因,我们这样做而不是分区(在大多数情况下,我们只对其中一个进行查询) 但有时我们需要做跨数据库的工作,我们可以根据请求知道要查询哪些数据库。我知道这可以通过每个API中的一个循环来实现,但这会非常难看,我需要一种编程方式(我们有很多API,它们可能会得到一个跨数据库查询) 例如,可能会有如下情况: $batchModel = new Batch(); // an array instead of a string

我们目前有多个数据库,物理上位于不同的位置。它们的结构完全相同。由于某些法律法规的原因,我们这样做而不是分区(在大多数情况下,我们只对其中一个进行查询)

但有时我们需要做跨数据库的工作,我们可以根据请求知道要查询哪些数据库。我知道这可以通过每个API中的一个循环来实现,但这会非常难看,我需要一种编程方式(我们有很多API,它们可能会得到一个跨数据库查询)

例如,可能会有如下情况:

$batchModel = new Batch();
// an array instead of a string here
$batchModel->setConnection(['region1', 'region2']);
$batchModel->all();

如果您根据请求选择数据库,我会选择中间件,即:

public function handle($request, Closure $next)
{        
    if( $request->has('something') ) {
        config(['database.default' => $request->something]);
    }
    return $next($request);
}

有意思。。据我所知,拉威尔并不天生支持这一点

我可以想出一个办法来实现这一点:

您可以在.env文件中创建多个数据库:

DB_CONNECTION=region1
DB_HOST=adomain.com
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
还有一个:

DB_CONNECTION=region2
DB_HOST=anotherdomain.com
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
然后将其添加到您的
数据库配置中:

'region1' => [
    'driver' => 'mysql',
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'strict' => true,
    'engine' => null,
],
对区域2执行相同操作。

现在扩展
Eloquent
类并添加类似“setMultipleConnections”的方法:

然后我认为您可以对该集合调用
all
find
等方法


这些都不管用,只是一个速写。我想你知道我在这里想要实现什么。这就是你要找的东西吗?

你完全误解了我,伙计。我的意思是是否有一种简洁的方法来循环所有的数据库,而不是如何设置默认的。你是对的,我完全误解了这个问题,弗雷德里克。我重读了你的问题,对于你的问题我没有一个好的解决方案。是的,这正是我想要的。但是我不能想出一个合适的方法来实现它。我这样做的方式对你来说不是一个合适的方法来实现它吗?我写的代码不是在测试,很可能不能马上工作。这只是为了说明解决这个问题的一种方法:)我做了类似的事情,通过传递一个回调函数将集合返回给一个函数。最初,我希望函数能够接受模型和查询生成器,并在所有区域执行查询,但我没有找到实现它的方法。
public method setMultipleConnections($databases, Model $model) {

   $collection = new Illuminate\Database\Eloquent\Collection;
   // Loop over $databases array and for each one of them get the collection. 
   foreach ($databases as $database) {
       $model = new $model;
       $model->setConnection($database);
       $model->get();

       $collections->merge($model);
   }

   return $collection;

}