dede如何调用其他数据库表的SQL?

99ANYc3cd6
预计阅读时长 30 分钟
位置: 首页 DEDE建站 正文

核心思路

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

dede sql 调用其他数据库表
(图片来源网络,侵删)
  1. 建立新的数据库连接:在 dedesql.class.php 中增加一个新的连接属性和方法。
  2. 执行查询:使用这个新连接来执行 SQL 语句并获取结果。
  3. 在模板中调用:通过自定义的标签或 PHP 代码在模板文件中显示查询到的数据。

修改核心类文件(最常用、最稳定)

这是最经典和可靠的方法,适合大多数情况,通过修改 dedesql.class.php,我们可以让系统原生支持多数据库连接。

步骤 1:备份原始文件

在进行任何修改之前,请务必备份 include/dedesql.class.php 文件,这是一个非常重要的习惯,可以防止误操作导致网站崩溃。

步骤 2:修改 include/dedesql.class.php 文件

用代码编辑器(如 VS Code, Sublime Text, Dreamweaver)打开 include/dedesql.class.php 文件。

  1. 在类的开头添加新属性class dedesql 的开头,找到类似 var $linkID; 的属性定义区域,在其下方添加一个新的属性来存储第二个数据库的连接 ID。

    dede sql 调用其他数据库表
    (图片来源网络,侵删)
    // 在这里添加你的新属性
    var $linkID2 = ''; // 用于存储第二个数据库的连接ID
  2. 添加新的连接方法 在类的末尾,找到 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;
    }
  3. 添加新的查询执行方法 为了在第二个数据库上执行查询,我们需要一个类似于 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;
    }
  4. 添加获取结果的方法 同样,我们需要从第二个查询结果中获取数据,添加 GetArray2() 方法。

    /**
     * 从第二个查询结果中获取一条记录并返回数组
     * @param resource $query 查询资源句柄
     * @return array
     */
    function GetArray2($query)
    {
        return @mysql_fetch_array($query, MYSQL_ASSOC);
    }

步骤 3:在需要的地方建立连接并查询

你可以在任何 PHP 文件中使用这个新功能了,最常见的地方是在 index.php 首页文件中进行调用。

dede sql 调用其他数据库表
(图片来源网络,侵删)

打开 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/ 目录下的文件。

  1. 创建标签文件include/taglib/ 目录下创建一个新文件,other.lib.php

  2. 编写标签逻辑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;
    }
    ?>
  3. 在模板中使用自定义标签 现在你可以在任何模板文件中直接使用这个标签了,无需在 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 已废弃,推荐使用 mysqliPDO,但修改 dedesql.class.php 的逻辑是相通的)。

-- 展开阅读全文 --
头像
数据结构与算法分析C语言描述答案是否完整且准确?
« 上一篇 2025-12-15
织梦dedecms电影模板如何适配最新电影?
下一篇 » 2025-12-15

相关文章

取消
微信二维码
支付宝二维码

目录[+]