| 方式 | 適用場景 | 優先級 | 特點 |
|---|---|---|---|
| 專案配置文件 | 單一資料庫、標準專案 | 最高(自動) | 約定優於配置、環境區分、調試覆蓋 |
| DSN 字串實例化 | 多資料庫、動態連接 | 手動 | 連接資訊集中、適合庫表切換 |
| 陣列參數實例化 | 多資料庫、程式化構建 | 手動 | 結構化、易於動態生成 |
| 模型類屬性定義 | 跨庫模型、特定表異庫 | 模型級 | 模型自帶連接、不影響全域 |
<?php
// Application/Common/Conf/config.php
return [
'DB_TYPE' => 'mysql',
'DB_HOST' => '127.0.0.1',
'DB_NAME' => 'thinkphp',
'DB_USER' => 'root',
'DB_PWD' => 'secret',
'DB_PORT' => '3306',
'DB_PREFIX' => 'think_',
'DB_CHARSET'=> 'utf8',
// 從庫配置(ThinkPHP 3.2+ 支援主從)
'DB_MASTER_NUM' => 1,
'DB_SLAVE_NO' => '',
'DB_DEPLOY_TYPE'=> 1, // 1 主從
'DB_RW_SEPARATE'=> true,
];
自動連接機制:首次模型操作時延遲連接,字段緩存至 Runtime/Data/_fields/。
<?php
$dsn = 'mysql://user:pwd@127.0.0.1:3306/dbname?charset=utf8';
$db = new Db($dsn); // 或 Think\Db::getInstance($dsn)
// 後續操作
$list = $db->query('SELECT * FROM think_user WHERE id > ?', [10]);
$db->execute('INSERT INTO think_log (msg) VALUES (?)', ['test']);
適用於:控制器中臨時連接第二資料庫、命令行腳本、多租戶動態切庫。
<?php
$config = [
'dbms' => 'mysql',
'username' => 'user',
'password' => 'pwd',
'hostname' => '127.0.0.1',
'hostport' => '3306',
'database' => 'dbname',
'dsn' => '', // 留空自動組裝
'params' => [PDO::ATTR_CASE => PDO::CASE_LOWER],
];
$db = new Db($config);
<?php
namespace Home\Model;
use Think\Model;
class ExternalLogModel extends Model {
// 方式 A:陣列
protected $connection = [
'dbms' => 'mysql',
'username' => 'log_user',
'password' => 'log_pwd',
'hostname' => '192.168.1.100',
'hostport' => '3306',
'database' => 'log_db',
];
// 方式 B:DSN 字串(二選一)
// protected $connection = 'mysql://log_user:log_pwd@192.168.1.100:3306/log_db';
protected $tableName = 'access_log'; // 實際表名
}
// 使用時自動連接 log_db
$log = D('ExternalLog');
$log->add(['ip' => '1.2.3.4', 'url' => '/api/test']);
// 實際執行:INSERT INTO log_db.access_log ...
<?php
return [
'DB_TYPE' => 'pdo', // 關鍵:驅動類型設為 pdo
'DB_DSN' => 'mysql:host=127.0.0.1;dbname=thinkphp;charset=utf8',
'DB_USER' => 'root',
'DB_PWD' => 'secret',
'DB_PREFIX' => 'think_',
];
// 前置檢查
if (!extension_loaded('pdo_mysql')) {
die('請安裝 php-pdo-mysql 擴充套件');
}
PDO 優勢:跨資料庫可移植、真實預處理防注入、支援事務嵌套、物件導向 API。
// ThinkPHP 連接時機
1. 實例化模型 → 觸發字段緩存 → 自動連接 SHOW COLUMNS
2. 首次 CRUD 操作 → 建立連接 → 執行 SQL
3. 長連接(pconnect) → 配置 'DB_PCONNECT' => true
// 連接池(Swoole/RoadRunner 環境)
// ThinkPHP 5.1+ 支援腳手架模式,需自行實作連接池中介軟體
| 現象 | 原因 | 解決 |
|---|---|---|
| Access denied | 帳號/密碼/主機權限 | GRANT ALL ON db.* TO 'user'@'%' IDENTIFIED BY 'pwd'; FLUSH PRIVILEGES; |
| Can't connect to MySQL server | 主機/端口/防火牆 | telnet host 3306、檢查 bind-address、security group |
| Unknown database | DB_NAME 拼寫錯誤 | 確認資料庫存在、字符集一致 |
| 字段緩存不更新 | 調試模式關閉、緩存未清 | 刪除 Runtime/Data/_fields/、或開啟 APP_DEBUG |
| 主從不同步 | Slave 延遲、配置錯誤 | SHOW SLAVE STATUS\G、關鍵查詢強制 Master |
config.php(通用)、config_dev.php、config_prod.php 環境覆蓋DB_PWD=getenv('DB_PASSWORD')PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4'ThinkPHP 的資料庫抽象層設計相當成熟,理解四種連接方式的優先級與適用場景,能讓你在單庫、多庫、主從、跨庫、遷移等複雜拓撲中遊刃有餘。