织梦CMS数据库操作有哪些核心方法?

99ANYc3cd6
预计阅读时长 23 分钟
位置: 首页 织梦建站 正文

织梦CMS的数据库操作主要分为两种方式:

织梦cms数据库操作
(图片来源网络,侵删)
  1. 使用Dede内置函数(推荐):这是最安全、最规范的方式,利用了织梦封装好的 dedesql 类,可以有效防止SQL注入,并且代码风格与织梦系统保持一致。
  2. 使用原生PHP的MySQL函数(不推荐):直接使用 mysql_query() 等旧版函数,这种方式已经过时,且存在安全风险,不推荐在二次开发中使用。

使用Dede内置函数($dsql$db

这是织梦二次开发的核心,织梦的全局对象 $dsql$db 就是操作数据库的利器。$dsql 是最常用、最强大的对象。

$dsql 对象简介

$dsqlDedeSql 类的一个实例,它封装了数据库的连接、查询、增、删、改等操作,在织梦的PHP文件中,它通常是全局可用的。

基本用法示例

假设我们要操作名为 dede_archives 的文章主表。

a) 执行一个查询(Execute() 方法)

这是最常用的查询方法,用于执行 SELECT 语句。

织梦cms数据库操作
(图片来源网络,侵删)
<?php
// 引入全局数据库对象(如果当前文件没有,通常需要引入:require_once(dirname(__FILE__)."/include/common.inc.php");
// 在织梦的很多页面中,$dsql 已经是全局变量了
// 1. 准备SQL语句
// 注意:表名前缀 `{dede_}` 是必须的,这样系统会自动替换为你真实的表前缀
$sql = "SELECT id, title, typeid FROM `{dede_archives}` ORDER BY id DESC LIMIT 10";
// 2. 执行查询
$dsql->Execute('me', $sql);
// 3. 遍历结果集
// Execute() 返回一个结果集对象,我们可以用下面的方式循环获取数据
while ($row = $dsql->GetArray('me')) {
    // $row 是一个关联数组,键名是字段名
    echo "文章ID: " . $row['id'] . "<br>";
    echo "文章标题: " . $row['title'] . "<br>";
    echo "分类ID: " . $row['typeid'] . "<hr>";
}
// 4. 释放结果集(虽然脚本结束时会自动释放,但良好习惯是手动释放)
$dsql->FreeResult('me');
?>

Execute() 方法详解:

  • $dsql->Execute('别名', 'SQL语句')
  • 第一个参数 '别名' 是给这个查询结果集起一个别名,在后续的 GetArray()GetObject() 中需要用到这个别名来区分不同的查询结果。
  • 第二个参数就是标准的SQL查询语句。

b) 获取单条记录(简化方法)

如果只需要查询一条记录,可以使用更简化的方法。

GetOne():获取一条记录,并以关联数组的形式返回。

<?php
$sql = "SELECT title FROM `{dede_archives}` WHERE id = 100";
$row = $dsql->GetOne($sql);
// $row 直接就是数组
if (is_array($row)) {
    echo "文章标题是: " . $row['title'];
} else {
    echo "未找到ID为100的文章。";
}
?>

GetOneRow():功能与 GetOne() 类似,但返回的是数字索引数组(较少使用)。

织梦cms数据库操作
(图片来源网络,侵删)

GetObject():获取一条记录,并以对象的形式返回。

<?php
$sql = "SELECT title FROM `{dede_archives}` WHERE id = 100";
$object = $dsql->GetObject($sql);
// $row 是一个对象,通过 -> 访问属性
if ($object) {
    echo "文章标题是: " . $object->title;
} else {
    echo "未找到ID为100的文章。";
}
?>

c) 执行更新、插入、删除(ExecuteNoneQuery() 方法)

这类操作不需要返回结果集,只需要执行SQL语句。

<?php
// 1. 更新操作
$update_sql = "UPDATE `{dede_archives}` SET title = '新标题' WHERE id = 100";
$dsql->ExecuteNoneQuery($update_sql);
echo "更新操作执行完毕,影响的行数: " . $dsql->GetAffectedRows() . "<br>";
// 2. 插入操作
$insert_sql = "INSERT INTO `{dede_archives}` (title, typeid, arcpinyin, pubdate, senddate) VALUES ('测试文章', 1, 'test', NOW(), NOW())";
$dsql->ExecuteNoneQuery($insert_sql);
echo "插入操作执行完毕,最后插入的ID: " . $dsql->GetLastID() . "<br>";
// 3. 删除操作
$delete_sql = "DELETE FROM `{dede_archives}` WHERE id = 101";
$dsql->ExecuteNoneQuery($delete_sql);
echo "删除操作执行完毕,影响的行数: " . $dsql->GetAffectedRows() . "<br>";
?>

d) 获取查询结果行数

<?php
$sql = "SELECT id FROM `{dede_archives}`";
$dsql->Execute('me', $sql);
$totalRows = $dsql->GetTotalRow('me'); // 使用之前Execute时定义的别名
echo "总共有 " . $totalRows . " 篇文章。";
?>

e) 安全查询(GetOne() 等方法的自动转义)

使用 $dsqlGetOne(), GetArray(), Execute() 等方法时,如果SQL语句中包含变量,必须使用 empirecms 提供的函数进行转义,以防止SQL注入。

// 错误示范!有SQL注入风险!
$id = $_GET['id'];
$sql = "SELECT title FROM `{dede_archives}` WHERE id = $id"; // 危险!
// 正确示范
$id = intval($_GET['id']); // 最安全的方式,如果是数字ID
// 或者使用织梦的过滤函数
$id = $dsql->GetOne("SELECT id FROM `{dede_member}` WHERE userid='".$dsql->EscapeString($_GET['user'])."'"); // 如果是字符串
$sql = "SELECT title FROM `{dede_archives}` WHERE id = $id"; // $id 已经是安全的整数
$row = $dsql->GetOne($sql);
?>

$dsql->EscapeString()$dsql 对象内置的转义函数,会对字符串进行安全处理。


使用原生PHP的MySQL函数($db 对象)

这种方式是织梦早期版本遗留下来的,功能较少,且 $db 对象没有 $dsql 那么完善的安全机制。除非有特殊需求,否则应尽量避免使用。

$db 对象通常是 mysqlmysqli 的一个连接资源。

基本用法示例

<?php
// 1. 执行查询
$sql = "SELECT id, title FROM `{dede_archives}` LIMIT 5";
$rs = $db->Execute($sql); // $db->Execute() 返回一个结果集对象
// 2. 遍历结果集
while (!$rs->EOF) { // 使用 EOF (End of File) 判断是否结束
    // rs->fields 是一个数字索引数组
    echo "ID: " . $rs->fields[0] . ", 标题: " . $rs->fields[1] . "<br>";
    // 移动到下一行
    $rs->MoveNext();
}
// 3. 获取字段值(通过字段名)
$rs->MoveFirst(); // 回到第一行
echo "第一篇文章的标题是: " . $rs->fields['title'];
// 4. 释放结果集
$rs->Close();
?>

执行更新、插入、删除

<?php
$sql = "UPDATE `{dede_archives}` SET title = '旧标题' WHERE id = 100";
$db->Execute($sql); // 直接执行,不返回结果
?>

最佳实践与注意事项

  1. 优先使用 $dsql:在99%的情况下,都应使用 $dsql 对象进行数据库操作。
  2. 表名加前缀:在SQL语句中写表名时,务必使用 {dede_} 作为前缀,如 {dede_archives},这样无论用户安装时设置什么前缀,代码都能正常工作。
  3. 变量过滤:所有来自用户输入的数据(GET, POST, COOKIE等)都不能直接拼接到SQL语句中,必须使用 intval() (对于数字) 或 $dsql->EscapeString() (对于字符串) 进行过滤。
  4. 及时释放资源:对于查询操作,当结果集使用完毕后,调用 $dsql->FreeResult('别名')$rs->Close() 来释放数据库资源,尤其是在循环或大量查询时,这可以避免服务器资源耗尽。
  5. 错误处理$dsql 提供了简单的错误处理机制,如果SQL执行出错,可以通过 $dsql->GetError() 获取错误信息,在开发阶段可以开启调试,方便排查问题。
  6. 事务处理:织梦也支持事务操作,确保一组SQL语句要么全部成功,要么全部失败,这在处理关联数据(如发布文章时同时插入文章、栏目、附加表等)时非常有用。

事务示例:

<?php
$dsql->SetQuery("INSERT INTO dede_archives...");
$dsql->Execute('add1');
$dsql->SetQuery("INSERT INTO dede_addonarticle...");
$dsql->Execute('add2');
// 如果上面两条都成功,则提交事务
if (!$dsql->GetError() && $dsql->GetAffectedRows('add1') > 0 && $dsql->GetAffectedRows('add2') > 0) {
    $dsql->Commit();
} else {
    // 如果有任何一条失败,则回滚事务
    $dsql->Rollback();
}
?>
操作类型 推荐方法 ($dsql) 说明
查询多条记录 $dsql->Execute('别名', $sql) + $dsql->GetArray('别名') 最灵活,适用于复杂查询
查询单条记录 $dsql->GetOne($sql) 返回关联数组,最常用
查询单条记录(对象) $dsql->GetObject($sql) 返回对象,面向对象风格
执行增/删/改 $dsql->ExecuteNoneQuery($sql) 不返回结果集
获取影响行数 $dsql->GetAffectedRows() 配合 ExecuteNoneQuery 使用
获取最后插入ID $dsql->GetLastID() 配合 INSERT 操作使用
字符串转义 $dsql->EscapeString($str) 防止SQL注入,必须使用

掌握 $dsql 的使用,是进行织梦CMS二次开发的基础和关键。

-- 展开阅读全文 --
头像
dede登录密码错误怎么办?
« 上一篇 03-01
C语言如何实现URL编码?
下一篇 » 03-01

相关文章

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

目录[+]