核心思路
DedeCMS 的所有数据库操作都依赖于一个核心类 dedesql,默认情况下,这个类只连接一个数据库(你在后台配置的那个),要连接第二个数据库,我们需要:

- 建立新的数据库连接:在
dedesql.class.php中增加一个新的连接属性和方法。 - 执行查询:使用这个新连接来执行 SQL 语句并获取结果。
- 在模板中调用:通过自定义的标签或 PHP 代码在模板文件中显示查询到的数据。
修改核心类文件(最常用、最稳定)
这是最经典和可靠的方法,适合大多数情况,通过修改 dedesql.class.php,我们可以让系统原生支持多数据库连接。
步骤 1:备份原始文件
在进行任何修改之前,请务必备份 include/dedesql.class.php 文件,这是一个非常重要的习惯,可以防止误操作导致网站崩溃。
步骤 2:修改 include/dedesql.class.php 文件
用代码编辑器(如 VS Code, Sublime Text, Dreamweaver)打开 include/dedesql.class.php 文件。
-
在类的开头添加新属性 在
class dedesql的开头,找到类似var $linkID;的属性定义区域,在其下方添加一个新的属性来存储第二个数据库的连接 ID。
(图片来源网络,侵删)// 在这里添加你的新属性 var $linkID2 = ''; // 用于存储第二个数据库的连接ID
-
添加新的连接方法 在类的末尾,找到
Close()方法后面,添加一个新的方法Connect2()用于连接第二个数据库。/** * 连接第二个数据库 * @param string $dbhost 数据库主机 * @param string $dbuser 数据库用户名 * @param string $dbpass 数据库密码 * @param string $dbname 数据库名称 * @param string $dbprefix 数据库表前缀 (可选) * @param string $pconnect 是否永久连接 (0 or 1) * @return bool */ function Connect2($dbhost, $dbuser, $dbpass, $dbname, $dbprefix='', $pconnect=0) { if($pconnect) { $this->linkID2 = @mysql_pconnect($dbhost, $dbuser, $dbpass); } else { $this->linkID2 = @mysql_connect($dbhost, $dbuser, $dbpass); } if (!$this->linkID2) { $this->DisplayError("无法连接到数据库服务器 '$dbhost'!"); exit(); } if (!@mysql_select_db($dbname, $this->linkID2)) { $this->DisplayError("无法选择数据库 '$dbname'!"); exit(); } @mysql_query("SET NAMES 'utf8'", $this->linkID2); // 设置字符集,根据你的实际情况修改,如 gbk $this->dbPrefix = $dbprefix; return $this->linkID2; } -
添加新的查询执行方法 为了在第二个数据库上执行查询,我们需要一个类似于
Execute()的方法,在Execute()方法附近,添加一个新的ExecQuery2()方法。/** * 在第二个数据库上执行一个SQL查询 * @param string $sql SQL查询语句 * @return resource 返回查询资源句柄 */ function ExecQuery2($sql) { if($this->linkID2 == '') { $this->DisplayError("尚未连接到第二个数据库!"); exit(); } $this->result2 = @mysql_query($sql, $this->linkID2); if(!$this->result2) { $this->DisplayError("SQL语句错误:"); $this->DisplayError(mysql_error()); $this->DisplayError("<br />SQL: $sql"); exit(); } return $this->result2; } -
添加获取结果的方法 同样,我们需要从第二个查询结果中获取数据,添加
GetArray2()方法。/** * 从第二个查询结果中获取一条记录并返回数组 * @param resource $query 查询资源句柄 * @return array */ function GetArray2($query) { return @mysql_fetch_array($query, MYSQL_ASSOC); }
步骤 3:在需要的地方建立连接并查询
你可以在任何 PHP 文件中使用这个新功能了,最常见的地方是在 index.php 首页文件中进行调用。

打开 index.php 文件,在 require_once(dirname(__FILE__)."/include/common.inc.php"); 这行代码之后,添加你的数据库连接和查询逻辑。
// 引入公共文件
require_once(dirname(__FILE__)."/include/common.inc.php");
// ====== 新增代码:连接并查询第二个数据库 ======
// 1. 定义第二个数据库的连接信息
$dbinfo2 = array(
'dbhost' => 'localhost', // 或其他 IP 地址
'dbuser' => 'your_other_db_user',
'dbpass' => 'your_other_db_password',
'dbname' => 'your_other_db_name',
'dbprefix' => 'pre_', // 第二个数据库的表前缀
'pconnect' => 0
);
// 2. 建立连接
$dsql->Connect2(
$dbinfo2['dbhost'],
$dbinfo2['dbuser'],
$dbinfo2['dbpass'],
$dbinfo2['dbname'],
$dbinfo2['dbprefix'],
$dbinfo2['pconnect']
);
// 3. 执行查询 (假设我们要查询另一个数据库中的 'ecs_articles' 表)
$sql2 = "SELECT * FROM {$dbinfo2['dbprefix']}ecs_articles ORDER BY article_id DESC LIMIT 10";
$dsql->ExecQuery2($sql2);
// 4. 准备数据传递给模板
$other_articles = array();
while ($row = $dsql->GetArray2($dsql->result2)) {
$other_articles[] = $row;
}
// 将数据注册为全局变量,以便在模板中使用
$GLOBALS['other_articles'] = $other_articles;
// ==============================================
// ... index.php 后续代码 ...
步骤 4:在模板文件中调用数据
打开你的首页模板文件 templets/default/index.htm,在需要显示这些文章的地方,使用 {dede:loop} 标签来循环输出。
<h3>来自其他系统的最新文章</h3>
<ul>
{dede:loop name='other_articles'}
<li>
<a href="[field:phpurl/]/view.php?aid=[field:article_id/]" target="_blank">
[field:title/]
</a>
<span class="arctime">([field:add_time/])</span>
</li>
{/dede:loop}
</ul>
注意:这里的 [field:phpurl/] 和 [field:add_time/] 等字段名,需要根据你第二个数据库表中的实际字段名来调整,直接使用 [field:字段名/] 即可。
使用原生 PHP 直接查询(更灵活,不修改核心)
如果你不想修改 DedeCMS 的核心文件,或者这个查询只在一个非常特定的页面使用,你可以直接在 PHP 文件中使用原生 PHP 来连接和查询数据库。
步骤 1:在 PHP 文件中直接编写查询代码
在 index.php 中:
require_once(dirname(__FILE__)."/include/common.inc.php");
// 定义第二个数据库信息
$dbhost2 = 'localhost';
$dbuser2 = 'your_other_db_user';
$dbpass2 = 'your_other_db_password';
$dbname2 = 'your_other_db_name';
// 连接数据库
$conn2 = mysql_connect($dbhost2, $dbuser2, $dbpass2) or die("连接数据库失败!");
mysql_select_db($dbname2, $conn2) or die("选择数据库失败!");
mysql_query("SET NAMES 'utf8'", $conn2);
// 执行查询
$sql2 = "SELECT title, article_id, add_time FROM pre_ecs_articles LIMIT 10";
$result2 = mysql_query($sql2, $conn2);
// 准备数据
$other_articles = array();
while ($row = mysql_fetch_assoc($result2)) {
$other_articles[] = $row;
}
// 释放资源
mysql_free_result($result2);
mysql_close($conn2);
// 注册全局变量
$GLOBALS['other_articles'] = $other_articles;
步骤 2:在模板中调用
与方法一完全相同,在模板中使用 {dede:loop} 循环输出 $GLOBALS['other_articles']。
创建自定义标签(最优雅,适合重复使用)
如果你需要在多个页面重复使用这个功能,创建一个自定义标签是最佳选择,这需要修改 include/taglib/ 目录下的文件。
-
创建标签文件 在
include/taglib/目录下创建一个新文件,other.lib.php。 -
编写标签逻辑 在
other.lib.php中编写代码,逻辑类似于方法一或方法二,但需要返回 DedeCMS 标签所需的数据格式。<?php if(!defined('DEDEINC')) exit('Request Error!'); function lib_other(&$ctag, &$refObj) { global $dsql; // 获取标签属性 $attlist = "row|10"; FillAttsDefault($ctag->CAttribute->Items, $attlist); $row = $ctag->CAttribute->Items['row']; // 连接第二个数据库 (使用方法一的逻辑) $dbinfo2 = array( 'dbhost' => 'localhost', 'dbuser' => 'your_other_db_user', 'dbpass' => 'your_other_db_password', 'dbname' => 'your_other_db_name', 'dbprefix' => 'pre_', ); $dsql->Connect2($dbinfo2['dbhost'], $dbinfo2['dbuser'], $dbinfo2['dbpass'], $dbinfo2['dbname'], $dbinfo2['dbprefix']); $sql2 = "SELECT * FROM {$dbinfo2['dbprefix']}ecs_articles ORDER BY article_id DESC LIMIT {$row}"; $dsql->ExecQuery2($sql2); $artlist = ''; while($row2 = $dsql->GetArray2($dsql->result2)) { $artlist .= " <li> <a href='{$row2['url']}'>{$row2['title']}</a> </li>\r\n"; } // 关闭第二个连接 (可选,但推荐) mysql_close($dsql->linkID2); return $artlist; } ?> -
在模板中使用自定义标签 现在你可以在任何模板文件中直接使用这个标签了,无需在 PHP 文件中做任何处理。
<h3>来自其他系统的最新文章</h3> <ul> {dede:other row='10'} <li> <a href="[field:url/]">[field:title/]</a> </li> {/dede:other} </ul>
总结与建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 修改核心类 | 功能强大,与系统无缝集成,可在任何PHP文件中使用,代码结构清晰。 | 直接修改核心文件,升级DedeCMS时可能被覆盖,需要重新修改。 | 需要在多个页面调用,且希望逻辑集中在PHP文件中的情况。(推荐首选) |
| 原生PHP | 不修改任何核心文件,简单直接,适合一次性查询。 | 代码分散,如果多处使用会造成重复,每个需要的地方都要写一遍连接代码。 | 只在单个特定页面进行一次性的数据查询。 |
| 自定义标签 | 最优雅,可复用性最高,模板调用非常简洁,符合DedeCMS的设计哲学。 | 设置相对复杂,需要创建新文件,理解标签机制。 | 功能需要在多个不同页面重复使用,希望模板文件尽可能干净的情况。 |
对于大多数用户来说,方法一 是最实用和最常用的解决方案,请务必在操作前备份文件,并确保你的 PHP 环境支持 mysql_* 系列函数(新版本 PHP 已废弃,推荐使用 mysqli 或 PDO,但修改 dedesql.class.php 的逻辑是相通的)。
