通达OA核心类库TD类深度解析

一、引言

TD类是通达OA提供的核心数据库操作类,封装了MySQL数据库的常用操作,提供了安全、便捷的数据库访问接口。本文将深入解析TD类的设计原理、成员方法和使用技巧,帮助您高效地进行数据库操作。

二、TD类概述

2.1 TD类定位

TD类位于 MYOA\webroot\inc\td.class.php,是OA数据库操作的核心类。

2.2 TD类特点

特点 说明
安全防护 自动进行SQL注入防护
连接管理 自动处理数据库连接和断开
简化操作 封装常用数据库操作方法
事务支持 支持事务处理
缓存集成 与Redis缓存无缝集成

2.3 TD类加载方式

php 复制代码
// 方式1:直接包含
include_once("inc/td.class.php");

// 方式2:通过auth.inc.php间接包含(推荐)
include_once("inc/auth.inc.php");

推荐使用方式2 ,因为 auth.inc.php 已包含了 td.class.php,且会进行权限验证。

三、TD类成员方法详解

3.1 构造方法

ini 复制代码
$td = new TD();

功能

  • 读取数据库配置(db_config.php)
  • 建立数据库连接
  • 选择默认数据库(TD_OA)

3.2 SQL执行方法

3.2.1 query() - 执行SQL语句

ini 复制代码
$result = $td->query($sql);

参数

  • $sql:SQL语句字符串

返回值

  • 成功:返回结果集资源
  • 失败:返回false

示例

php 复制代码
// 查询
$result = $td->query("SELECT * FROM user WHERE uid = 1");

// 插入
$td->query("INSERT INTO user (username, password) VALUES ('test', '123456')");

// 更新
$td->query("UPDATE user SET name = '张三' WHERE uid = 1");

// 删除
$td->query("DELETE FROM user WHERE uid = 1");

3.2.2 execute() - 执行SQL语句(忽略结果)

ini 复制代码
$success = $td->execute($sql);

参数

  • $sql:SQL语句字符串

返回值

  • 成功:返回true
  • 失败:返回false

适用场景:执行不需要返回结果的SQL语句(如INSERT、UPDATE、DELETE)。

3.3 结果集处理方法

3.3.1 fetch_array() - 获取关联数组

ini 复制代码
$row = $td->fetch_array($result);

参数

  • $result:结果集资源

返回值

  • 成功:返回关联数组
  • 失败:返回false

示例

ini 复制代码
$result = $td->query("SELECT * FROM user WHERE uid = 1");
$user = $td->fetch_array($result);
echo $user['username']; // 输出用户名

3.3.2 fetch_row() - 获取索引数组

ini 复制代码
$row = $td->fetch_row($result);

参数

  • $result:结果集资源

返回值

  • 成功:返回索引数组
  • 失败:返回false

示例

ini 复制代码
$result = $td->query("SELECT username, name FROM user WHERE uid = 1");
$row = $td->fetch_row($result);
echo $row[0]; // 输出用户名
echo $row[1]; // 输出姓名

3.3.3 fetch_object() - 获取对象

ini 复制代码
$obj = $td->fetch_object($result);

参数

  • $result:结果集资源

返回值

  • 成功:返回对象
  • 失败:返回false

示例

ini 复制代码
$result = $td->query("SELECT * FROM user WHERE uid = 1");
$user = $td->fetch_object($result);
echo $user->username; // 输出用户名

3.3.4 num_rows() - 获取记录数

ini 复制代码
$count = $td->num_rows($result);

参数

  • $result:结果集资源

返回值

  • 记录总数

示例

ini 复制代码
$result = $td->query("SELECT * FROM user");
$count = $td->num_rows($result);
echo "共有 $count 个用户";

3.3.5 free_result() - 释放结果集

bash 复制代码
$td->free_result($result);

参数

  • $result:结果集资源

适用场景:处理大量数据时,及时释放结果集节省内存。

3.4 安全方法

3.4.1 escape() - SQL转义

ini 复制代码
$safe_str = $td->escape($str);

参数

  • $str:需要转义的字符串

返回值

  • 转义后的安全字符串

示例

ini 复制代码
$username = $td->escape($_GET['username']);
$sql = "SELECT * FROM user WHERE username = '$username'";
$result = $td->query($sql);

重要性:防止SQL注入攻击。

3.5 事务处理方法

3.5.1 begin() - 开始事务

ruby 复制代码
$td->begin();

3.5.2 commit() - 提交事务

scss 复制代码
$td->commit();

3.5.3 rollback() - 回滚事务

scss 复制代码
$td->rollback();

事务示例

scss 复制代码
try {
    $td->begin();
    
    // 操作1:扣减库存
    $td->query("UPDATE product SET stock = stock - 1 WHERE product_id = 1");
    
    // 操作2:添加订单
    $td->query("INSERT INTO order (product_id, quantity) VALUES (1, 1)");
    
    $td->commit();
    echo _("操作成功");
} catch (Exception $e) {
    $td->rollback();
    echo _("操作失败") . $e->getMessage();
}

事务流程图

3.6 缓存方法

3.6.1 cache_get() - 获取缓存

ini 复制代码
$data = $td->cache_get($key);

参数

  • $key:缓存键名

返回值

  • 缓存数据或false

3.6.2 cache_set() - 设置缓存

bash 复制代码
$td->cache_set($key, $value, $expire = 3600);

参数

  • $key:缓存键名
  • $value:缓存数据
  • $expire:过期时间(秒),默认3600秒

3.6.3 cache_delete() - 删除缓存

bash 复制代码
$td->cache_delete($key);

参数

  • $key:缓存键名

缓存示例

ini 复制代码
$cache_key = "user_list";
$user_list = $td->cache_get($cache_key);

if (!$user_list) {
    // 从数据库查询
    $result = $td->query("SELECT * FROM user");
    $user_list = array();
    while ($row = $td->fetch_array($result)) {
        $user_list[] = $row;
    }
    
    // 设置缓存,有效期1小时
    $td->cache_set($cache_key, $user_list, 3600);
}

// 使用缓存数据
print_r($user_list);

3.7 其他方法

3.7.1 insert_id() - 获取自增ID

bash 复制代码
$td->query("INSERT INTO user (username) VALUES ('test')");
$uid = $td->insert_id();
echo "新用户ID:$uid";

3.7.2 affected_rows() - 获取受影响行数

bash 复制代码
$td->query("UPDATE user SET status = 1 WHERE dept_id = 1");
$count = $td->affected_rows();
echo "更新了 $count 条记录";

3.7.3 getVersion() - 获取MySQL版本

bash 复制代码
$version = $td->getVersion();
echo "MySQL版本:$version";

3.7.4 close() - 关闭连接

perl 复制代码
$td->close();

注意:通常不需要手动调用,PHP脚本结束时会自动关闭。

四、TD类设计原理

4.1 类结构

4.2 连接管理机制

4.3 SQL注入防护机制

escape方法处理的字符

原始字符 转义后
' '
" "
`` \
NULL \0
\n \n
\r \r

五、TD类使用最佳实践

5.1 查询数据

php 复制代码
<?php
$td = new TD();

// 查询单条记录
$sql = "SELECT * FROM user WHERE uid = 1";
$result = $td->query($sql);
$user = $td->fetch_array($result);

// 查询多条记录
$sql = "SELECT * FROM user WHERE dept_id = 10";
$result = $td->query($sql);
$users = array();
while ($row = $td->fetch_array($result)) {
    $users[] = $row;
}
$td->free_result($result); // 释放结果集
?>

5.2 插入数据

php 复制代码
<?php
$td = new TD();

// 安全插入
$username = $td->escape($_POST['username']);
$password = md5($_POST['password']);
$name = $td->escape($_POST['name']);

$sql = "INSERT INTO user (username, password, name) 
        VALUES ('$username', '$password', '$name')";

if ($td->query($sql)) {
    $uid = $td->insert_id();
    echo "添加成功,用户ID:$uid";
} else {
    echo "添加失败";
}
?>

5.3 更新数据

php 复制代码
<?php
$td = new TD();

$uid = intval($_POST['uid']);
$name = $td->escape($_POST['name']);
$email = $td->escape($_POST['email']);

$sql = "UPDATE user SET name = '$name', email = '$email' WHERE uid = $uid";

if ($td->query($sql)) {
    $count = $td->affected_rows();
    echo "更新了 $count 条记录";
} else {
    echo "更新失败";
}
?>

5.4 删除数据

php 复制代码
<?php
$td = new TD();

$uid = intval($_GET['uid']);

$sql = "DELETE FROM user WHERE uid = $uid";

if ($td->query($sql)) {
    echo "删除成功";
} else {
    echo "删除失败";
}
?>

5.5 分页查询

ini 复制代码
<?php
$td = new TD();

$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
$page_size = 10;
$offset = ($page - 1) * $page_size;

// 查询数据
$sql = "SELECT * FROM user ORDER BY uid DESC LIMIT $offset, $page_size";
$result = $td->query($sql);

// 查询总数
$count_sql = "SELECT COUNT(*) AS total FROM user";
$count_result = $td->query($count_sql);
$count_row = $td->fetch_array($count_result);
$total = $count_row['total'];
$total_pages = ceil($total / $page_size);
?>

5.6 复杂查询

php 复制代码
<?php
$td = new TD();

$keyword = $td->escape($_GET['keyword']);
$dept_id = isset($_GET['dept_id']) ? intval($_GET['dept_id']) : 0;

$sql = "SELECT u.*, d.dept_name 
        FROM user u 
        LEFT JOIN dept d ON u.dept_id = d.dept_id 
        WHERE 1=1";

if ($keyword) {
    $sql .= " AND (u.username LIKE '%$keyword%' OR u.name LIKE '%$keyword%')";
}

if ($dept_id > 0) {
    $sql .= " AND u.dept_id = $dept_id";
}

$sql .= " ORDER BY u.create_time DESC";

$result = $td->query($sql);
?>

六、常见问题与解决方案

6.1 连接失败

现象:无法连接数据库

排查步骤

解决方案

  • 检查 db_config.php 配置是否正确
  • 确认MySQL服务已启动
  • 验证端口号(默认3336)
  • 检查防火墙设置

6.2 SQL注入风险

现象:可能存在SQL注入漏洞

解决方案

lua 复制代码
Mermaid 渲染失败: Parse error on line 6:
...--> C1[使用$td->escape()]    C --> C2[使用i
-----------------------^
Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'PS'

安全编码规范

  • 字符串类型使用 $td->escape()
  • 数字类型使用 intval()floatval()
  • 不要直接拼接用户输入到SQL语句

6.3 性能问题

现象:查询速度慢

优化方案

优化建议

  • 为经常查询的字段添加索引
  • 避免使用 SELECT *,只查询需要的字段
  • 使用 LIMIT 限制返回数据量
  • 使用缓存减少数据库查询
相关推荐
小Ti客栈2 小时前
Spring Boot 集成 Springdoc-OpenAPI 与 Knife4j实现接口文档与可视化调试
java·spring boot·后端
Ai拆代码的曹操3 小时前
Spring 事务 REQUIRES_NEW 嵌套调用:连接池翻倍的秘密
java·后端·spring
IT_陈寒4 小时前
SpringBoot这个分页坑,我踩了三天才爬出来
前端·人工智能·后端
颜酱4 小时前
05 | 召回前置准备:根据业务数据库生成各数据库(读取配置阶段)
前端·人工智能·后端
Wang's Blog4 小时前
Go-Zero项目开发24: 基于Bitmap实现群聊消息已读未读
开发语言·后端·golang
Conan在掘金5 小时前
鸿蒙报错速查:struct 里嵌 namespace 声明就炸,根因 + 真解法
后端
东方小月5 小时前
从零开发一个 Coding Agent(三):EventStream 事件流通道设计与实现
前端·人工智能·后端
卫子miao6 小时前
如何评价当前大语言模型的记忆机制?
后端·架构
神奇小汤圆6 小时前
为什么 AQS 成为 Java 并发的基石?
后端
星栈7 小时前
MCP 从 stdio 迁到 SSE,踩了 5 个传输层坑
人工智能·后端·架构