通达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 限制返回数据量
  • 使用缓存减少数据库查询
相关推荐
Gopher_HBo1 小时前
Go语言学习笔记(十八)Gin处理Session
后端
谭光志2 小时前
工具塞满上下文窗口怎么办?深度拆解 AI Agent Tool Search 按需加载实现原理
前端·后端·ai编程
她说..2 小时前
Java 默认值设置方式
java·开发语言·后端·springboot
foggyprojects2 小时前
从0开始,一句话启动AI DataAgent
后端·数据分析·ai编程
郡杰2 小时前
一些基础和问题解决
后端
陈随易3 小时前
前端项目部署只要30秒
前端·后端·程序员
YIAN3 小时前
从零手写文件读取 MCP 服务:一文吃透 Model Context Protocol 全链路通信原理
前端·后端·mcp
Imchendiana3 小时前
《狂人日记NO.9》— 前后端一把梭,我的全栈实录
前端·后端
学渣超3 小时前
记一次分布式事务数据不一致的排查之旅:从超时到索引,层层剥茧
java·后端·架构