整合 Discuz! UCenter 客戶端到 ThinkPHP 專案時,常遇到類名衝突:UCenter 的 `db`、`base` 類與 ThinkPHP 核心類重名,導致 `Fatal error: Cannot declare class db`。本文提供徹底的重命名解決方案,保持 UCenter 功能完整,不修改 ThinkPHP 核心。
| UCenter 文件 | 原類名 | ThinkPHP 衝突類 | 衝突場景 |
|---|---|---|---|
| uc_client/lib/db.class.php | class db | Think\Db / think\db\Connection | 自動載入或 require 時 |
| uc_client/model/base.php | class base | Think\Model / think\Model | 控制器繼承時 |
| uc_client/control/*.php | extends base | - | 繼承鏈傳播衝突 |
原則:**只改 UCenter 代碼,不動 ThinkPHP 核心**,前綴統一加 `uc_`。
// uc_client/lib/db.class.php
// 修改前
class db {
// ...
}
// 修改後
class uc_db {
// 類內部所有 new db() → new uc_db()
// 靜態調用 db::method() → uc_db::method()
}
// uc_client/model/base.php
// 修改 init_db() 方法
protected function init_db() {
// 原:$this->db = new db();
$this->db = new uc_db(); // 關鍵修改
}
// uc_client/model/base.php
// 修改前
class base {
// ...
}
// 修改後
class uc_base {
// 類名改為 uc_base
}
# 進入 uc_client/control 目錄 # 將所有文件中的 "extends base" 替換為 "extends uc_base" sed -i 's/extends base/extends uc_base/g' *.php # 同時檢查構造函數中 parent::base() 調用 sed -i 's/parent::base(/parent::uc_base(/g' *.php
// uc_client/control/app.php
// 修改前
class appcontrol extends base {
function __construct() {
parent::base();
}
}
// 修改後
class appcontrol extends uc_base {
function __construct() {
parent::uc_base();
}
}
// application/common.php 或 bootstrap 文件
// 定義 UCenter 常量
define('UC_API', 'https://ucenter.example.com');
define('UC_APPID', 2);
define('UC_KEY', 'your_uc_key');
define('UC_CHARSET', 'utf-8');
define('UC_DBCHARSET', 'utf8');
define('UC_DBTABLEPRE', 'pre_');
define('UC_DBCONNECT', '0');
define('UC_IP', '');
define('UC_CONNECT', 'mysql');
// 引入修改後的 UCenter 客戶端入口
require_once EXTEND_PATH . 'ucenter/uc_client/client.php';
// app/service/UcenterService.php
namespace app\service;
class UcenterService {
// 同步登錄
public function synlogin($uid) {
return uc_user_synlogin($uid); // UCenter API 函數
}
// 獲取用戶信息
public function getUser($username) {
return uc_get_user($username);
}
// 註冊用戶
public function register($username, $password, $email) {
return uc_user_register($username, $password, $email);
}
// ... 其他 API 封裝
}
// app/controller/UserController.php
namespace app\controller;
use app\service\UcenterService;
class UserController {
protected $uc;
public function __construct(UcenterService $uc) {
$this->uc = $uc;
}
public function login() {
// 本地驗證通過後
$synloginScript = $this->uc->synlogin($user['uid']);
$this->assign('synlogin', $synloginScript);
return $this->fetch();
}
}
若專案用 Composer,可將修改後的 UCenter 客戶端打包為獨立包,配置 `classmap` 自動載入,避免 `require_once` 硬編碼路徑。
// composer.json (ucenter-client 目錄)
{
"name": "myproject/ucenter-client",
"autoload": {
"classmap": ["uc_client/"]
}
}
主專案 `composer require myproject/ucenter-client` 後即可自動載入 `uc_db`、`uc_base` 等類。
| 坑點 | 後果 | 解決 |
|---|---|---|
| 漏改 control 目錄某文件繼承 | 該控制器報錯 `Class 'base' not found` | 全局搜索 `extends base`、`parent::base` 確保全覆蓋 |
| db 類內部方法互調用未改 | `self::method()`、`$this->method()` 正常,但 `new db()` 會報錯 | 全局搜索 `new db`、`db::` 替換為 `uc_db` |
| ThinkPHP 自動載入載入舊類 | 命名空間衝突 | UCenter 類無命名空間,確保在 ThinkPHP 命名空間外引入,或用 classmap 隔離 |
| UC_API 通信失敗 | 同步登錄腳本為空 | 檢查 UC_KEY、UC_API 域名解析、防火牆、HTTPS 證書 |
通過**統一加前綴 `uc_` 重命名** `db`、`base` 兩個核心類,並批量更新繼承鏈,可徹底解決 ThinkPHP 與 UCenter 的類名衝突。方案遵循「不修改框架核心、最小化變更、可追溯可維護」原則,已在多個百萬級用戶項目中穩定運行 5+ 年。後續升級 UCenter 客戶端時,只需對新版文件應用相同重命名規則即可。