首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

ThinkPHP 資料庫連線配置技巧:多環境、多資料庫、動態切換

     編輯:PHP 綜合知識

配置策略概覽

ThinkPHP 支援靈活的資料庫配置方式。本文介紹三種常用配置技巧:獨立配置檔複用、控制器動態連線、多資料庫切換。

技巧一:獨立配置檔複用(推薦)

1. 建立獨立資料庫配置檔

`Conf/db.php`(與入口檔同級):

<?php
return array(
    'DB_TYPE'   => 'mysqli',
    'DB_HOST'   => 'localhost',
    'DB_NAME'   => 'demo',
    'DB_USER'   => 'root',
    'DB_PWD'    => 'root',
    'DB_PREFIX' => 'think_',
    'DB_CHARSET'=> 'utf8',
    'DB_PARAMS' => array(
        \PDO::ATTR_PERSISTENT => true,  // 持久連線
    ),
);

2. 專案配置檔引入合併

`Conf/config.php`:

<?php
$appConfig = array(
    'URL_MODEL'     => 2,
    'APP_DEBUG'     => true,
    'LOG_RECORD'    => true,
    // ... 其他應用配置
);

$dbConfig = include 'db.php';  // 引入獨立配置

return array_merge($appConfig, $dbConfig);

3. 後台/多入口同步共享

後台入口 `Admin/Conf/config.php` 同樣引入:

$dbConfig = include '../../Conf/db.php';  // 相對路徑指向同一檔案
return array_merge($adminConfig, $dbConfig);

優點:修改一處 `db.php`,前後台同步生效,避免配置不一致。

技巧二:控制器中動態連接另一資料庫

臨時連接不同資料庫(如跨庫查詢、同步數據):


class DataAction extends Action
{
    public function sync()
    {
        $config = array(
            'dbms'        => 'mysqli',      // 驅動類型
            'username'    => 'remote_user',
            'password'    => 'remote_pass',
            'hostname'    => '192.168.1.100',
            'database'    => 'remote_db',
            'hostport'    => '3306',
            'dsn'         => '',            // 可選完整 DSN
        );
        
        // 實例化 Db 類(非 Model)
        $db = new Db($config);
        
        // 直接查詢
        $list = $db->table('remote_table')->where('status=1')->select();
        
        // 或執行原生 SQL
        $db->execute("INSERT INTO local_table SELECT * FROM remote_table WHERE ...");
    }
}

注意

  • `Db` 類鍵名固定:`dbms`、`username`、`password`、`hostname`、`database`、`hostport`、`dsn`
  • 此方式建立獨立連線,不影響預設 Model 連線
  • 用完可手動 `$db->close()` 或腳本結束自動釋放

技巧三:Model 級多資料庫切換(進階)

不同 Model 對應不同資料庫:

1. 配置多資料庫

`Conf/db.php`:


return array(
    'DB_CONFIG' => array(
        'main' => array(
            'DB_TYPE' => 'mysqli',
            'DB_HOST' => 'localhost',
            'DB_NAME' => 'main_db',
            'DB_USER' => 'root',
            'DB_PWD'  => 'pass',
        ),
        'logs' => array(
            'DB_TYPE' => 'mysqli',
            'DB_HOST' => '192.168.1.10',
            'DB_NAME' => 'logs_db',
            'DB_USER' => 'log_user',
            'DB_PWD'  => 'log_pass',
        ),
        'archive' => array(
            'DB_TYPE' => 'mysqli',
            'DB_HOST' => '192.168.1.20',
            'DB_NAME' => 'archive_db',
            'DB_USER' => 'arc_user',
            'DB_PWD'  => 'arc_pass',
        ),
    ),
);

2. 基類 Model 實現自動切換


class BaseModel extends Model
{
    protected $dbConfigKey = 'main';  // 預設資料庫
    
    public function __construct($data = '', $tableName = '', $dbConfig = '')
    {
        if ($dbConfig) {
            $this->dbConfigKey = $dbConfig;
        }
        parent::__construct($data, $tableName);
    }
    
    protected function _connect()
    {
        if ($this->_db) return $this->_db;
        
        $config = C('DB_CONFIG.' . $this->dbConfigKey);
        if (!$config) {
            E("Database config '{$this->dbConfigKey}' not found");
        }
        
        $this->_db = Db::getInstance($config);
        return $this->_db;
    }
}

3. 具體 Model 指定資料庫


class UserModel extends BaseModel
{
    protected $dbConfigKey = 'main';
    protected $tableName = 'user';
}

class LogModel extends BaseModel
{
    protected $dbConfigKey = 'logs';
    protected $tableName = 'access_log';
}

class ArchiveModel extends BaseModel
{
    protected $dbConfigKey = 'archive';
    protected $tableName = 'old_data';
}

4. 使用範例


// 自動使用 main 資料庫
$user = M('User')->find(1);

// 自動使用 logs 資料庫
$logs = M('Log')->where('date > "2024-01-01"')->select();

// 臨時覆蓋
$temp = M('User', 'user', 'logs')->find(1);  // 第三參數指定 dbConfigKey

技巧四:環境區分配置(開發/測試/生產)

利用 `ThinkPHP/Conf/convention.php` 慣例配置 + 專案配置覆蓋機制:


// 專案根目錄建立環境檢測
define('APP_ENV', getenv('APP_ENV') ?: 'development');

// Conf/config.php
$envConfigs = array(
    'development' => array(
        'DB_HOST' => 'localhost',
        'DB_NAME' => 'dev_db',
        'APP_DEBUG' => true,
    ),
    'testing' => array(
        'DB_HOST' => '192.168.1.10',
        'DB_NAME' => 'test_db',
        'APP_DEBUG' => true,
    ),
    'production' => array(
        'DB_HOST' => 'db.master.internal',
        'DB_NAME' => 'prod_db',
        'APP_DEBUG' => false,
        'DB_PARAMS' => array(\PDO::ATTR_PERSISTENT => true),
    ),
);

return array_merge($commonConfig, $envConfigs[APP_ENV]);

部署時設定環境變數:

# Nginx + PHP-FPM
fastcgi_param APP_ENV production;

# Apache
SetEnv APP_ENV production

# Docker
ENV APP_ENV=production

最佳實踐總結

場景推薦方案關鍵點
單資料庫、前後台共享獨立 db.php + array_merge一處修改、多處生效
臨時跨庫查詢控制器 new Db($config)獨立連線、不影響主連線
多業務模組分庫BaseModel + dbConfigKeyModel 級自動切換、透明使用
多環境部署環境變數 + 陣列合併配置與代碼分離、安全無硬編碼
讀寫分離Db 類擴展或中間件主庫寫、從庫讀、自動路由

合理規劃資料庫配置策略,能大幅降低維護成本,避免配置漂移導致的生產事故。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved