Drupal 7 支持同時連接多個數據庫,但配置不當易導致「表不存在」「數據寫入錯誤庫」「連接交叉」等疑難雜症。本文系統梳理配置方法、切換機制、常見坑點與解決方案。
在 settings.php 中將 $db_url 定義為關聯數組:
$db_url['default'] = 'mysql://user:pass@localhost/drupal_main';
$db_url['external'] = 'mysql://user:pass@localhost/external_db';
$db_url['legacy'] = 'pgsql://user:pass@localhost/legacy_data'; // 支持不同驅動
<?php
// 切換到 external 數據庫
db_set_active('external');
// 執行查詢(使用 external 連接)
$result = db_query("SELECT * FROM {external_table} WHERE id = :id", [':id' => 123]);
// 重要:用完立即切回默認連接!
db_set_active('default');
db_set_active('xxx') 必須配對 db_set_active('default')try/finally 確保切回// 安全模式
db_set_active('external');
try {
// ... 數據庫操作 ...
} finally {
db_set_active('default');
}
現象: SQL 語法正確但報「Table 'main_db.external_table' doesn't exist」
原因: 忘記 db_set_active('default'),後續代碼仍在 external 連接上執行
排查: 搜索代碼中所有 db_set_active,確保成對出現,異常路徑也覆蓋
Drupal 通過 {table_name} 自動添加前綴,但前綴綁定於當前活躍連接的配置。
// 正確:在 external 連接下,{users} 解析為 external_db.prefix_users
db_set_active('external');
db_query("SELECT * FROM {users}"); // 使用 external 的前綴配置
// 錯誤:在 default 連接下查 external 表
db_set_active('default');
db_query("SELECT * FROM {external_table}"); // 解析為 main_db.prefix_external_table → 不存在
多站點共用用戶表時,在 settings.php 配置前綴映射:
$db_prefix = array(
'default' => '', // 主站表無前綴
'users' => 'shared.', // users 表指向 shared_db.shared_users
'sessions' => 'shared.',
'role' => 'shared.',
'users_roles' => 'shared.',
// 格式:'表名' => '數據庫名.前綴' 或 '前綴'
);
效果: 所有站點操作 {users} 實際讀寫 shared_db.shared_users,實現單點登錄 (SSO) 基礎。
// 明確指定 external_db 表
db_query("SELECT uid FROM external_db.z_table WHERE name = :name", [':name' => 'admin']);
// 注意:不使用 {table} 語法,直接寫死庫.表
function mymodule_external_operation() {
global $db_url; // 必須 global 聲明
// 動態添加連接(僅當前請求有效)
$db_url['temp_log'] = 'mysqli://log_user:pass@log_host/log_db';
db_set_active('temp_log');
try {
db_insert('access_log')->fields([...])->execute();
} finally {
db_set_active('default');
}
}
DatabaseSwitcher 統一管理 setActive()/restore()try/finally 中external, legacy, analytics)而非 db1, db2db_set_active 驗證切換邏輯\Drupal::service('database')->getConnection('external')db_set_active(),改用 $connection = \Drupal::database('external'); $connection->query(...)settings.php 中 $databases 陣列結構變更規範管理多數據庫連接,是構建穩健 Drupal 多系統集成應用的基石。