从主数据库获取数据库凭据,然后连接到不同的数据库
Get database credentials from master database, then connect to different database
我有一个实例化 Web 应用程序,它为每个实例使用不同的数据库,但使用相同的文件。
我希望我的应用程序在启动时执行的操作:
- 从主实例获取数据库凭据table。此实例 table 位于我在 app/config/database.php.
中定义的默认 'mysql' 连接中
- 从那时起连接到实例数据库(我不再需要主实例数据库)
我曾尝试在我的 App:before() 事件中执行此操作,但那行不通,因为我的主数据库中没有会话 table。如果我在 database.php 中的 return array() 之前执行此操作,它显然无法连接,因为它还没有正确的主数据库凭据。
我应该在哪里做这个?我应该只禁用会话并在我的 App::before() 中执行它,然后再启用会话吗?
不认为这是可能的,但这是一种可能性。
读/写连接数
有时您可能希望对 SELECT
语句使用一个数据库连接,对 INSERT
、UPDATE
和 DELETE
语句使用另一个数据库连接。 Laravel 使这变得轻而易举,无论您使用原始查询、查询生成器还是 Eloquent ORM,都将始终使用正确的连接。
要了解应该如何配置读/写连接,让我们看一下这个例子:
'mysql' => array(
'read' => array(
'host' => '192.168.1.1',
),
'write' => array(
'host' => '196.168.1.2'
),
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
请注意,已将两个键添加到配置数组:读取和写入。这两个键都有包含一个键的数组值:主机。读取和写入连接的其余数据库选项将从主 mysql 数组中合并。因此,如果我们希望覆盖主数组中的值,我们只需要将项目放在读写数组中。因此,在这种情况下,192.168.1.1
将用作 "read" 连接,而 192.168.1.2
将用作 "write" 连接。主 mysql 数组中的数据库凭据、前缀、字符集和所有其他选项将在两个连接之间共享。
经过几个小时的实验和尝试,我发现最好的选择确实是在 /app/config/database.php 文件中手动创建一个 PDO 实例,并通过这种方式获取数据库凭据:
// Get instance row
if (!App::runningInConsole() && !array_key_exists('instance_found', $_ENV)) {
$conn = new PDO('mysql:dbname=instances;host=127.0.0.1', 'root', 'password');
$stmt = $conn->prepare('SELECT * FROM instances WHERE http_host=?');
$stmt->bindParam(1, $_SERVER['HTTP_HOST']);
$stmt->execute();
$instance = $stmt->fetch(PDO::FETCH_OBJ);
$conn = null;
if (!$instance) {
return Response::make('Whoops!', 404);
} else {
$_ENV['instance_found'] = true;
$database = $instance->mysql_database;
$username = $instance->mysql_username;
$password = $instance->mysql_password;
}
}
我有一个实例化 Web 应用程序,它为每个实例使用不同的数据库,但使用相同的文件。
我希望我的应用程序在启动时执行的操作:
- 从主实例获取数据库凭据table。此实例 table 位于我在 app/config/database.php. 中定义的默认 'mysql' 连接中
- 从那时起连接到实例数据库(我不再需要主实例数据库)
我曾尝试在我的 App:before() 事件中执行此操作,但那行不通,因为我的主数据库中没有会话 table。如果我在 database.php 中的 return array() 之前执行此操作,它显然无法连接,因为它还没有正确的主数据库凭据。
我应该在哪里做这个?我应该只禁用会话并在我的 App::before() 中执行它,然后再启用会话吗?
不认为这是可能的,但这是一种可能性。
读/写连接数
有时您可能希望对 SELECT
语句使用一个数据库连接,对 INSERT
、UPDATE
和 DELETE
语句使用另一个数据库连接。 Laravel 使这变得轻而易举,无论您使用原始查询、查询生成器还是 Eloquent ORM,都将始终使用正确的连接。
要了解应该如何配置读/写连接,让我们看一下这个例子:
'mysql' => array(
'read' => array(
'host' => '192.168.1.1',
),
'write' => array(
'host' => '196.168.1.2'
),
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
请注意,已将两个键添加到配置数组:读取和写入。这两个键都有包含一个键的数组值:主机。读取和写入连接的其余数据库选项将从主 mysql 数组中合并。因此,如果我们希望覆盖主数组中的值,我们只需要将项目放在读写数组中。因此,在这种情况下,192.168.1.1
将用作 "read" 连接,而 192.168.1.2
将用作 "write" 连接。主 mysql 数组中的数据库凭据、前缀、字符集和所有其他选项将在两个连接之间共享。
经过几个小时的实验和尝试,我发现最好的选择确实是在 /app/config/database.php 文件中手动创建一个 PDO 实例,并通过这种方式获取数据库凭据:
// Get instance row
if (!App::runningInConsole() && !array_key_exists('instance_found', $_ENV)) {
$conn = new PDO('mysql:dbname=instances;host=127.0.0.1', 'root', 'password');
$stmt = $conn->prepare('SELECT * FROM instances WHERE http_host=?');
$stmt->bindParam(1, $_SERVER['HTTP_HOST']);
$stmt->execute();
$instance = $stmt->fetch(PDO::FETCH_OBJ);
$conn = null;
if (!$instance) {
return Response::make('Whoops!', 404);
} else {
$_ENV['instance_found'] = true;
$database = $instance->mysql_database;
$username = $instance->mysql_username;
$password = $instance->mysql_password;
}
}