通达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 限制返回数据量
  • 使用缓存减少数据库查询
相关推荐
金銀銅鐵8 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(上)
java·后端·ai编程
念何架构之路9 小时前
go-grpc设计思想
开发语言·后端·golang
system_error_x9 小时前
SpringBoot 集成 Thymeleaf 简洁入门
java·spring boot·后端
步行cgn11 小时前
Spring MVC 视图机制的核心接口与类
java·开发语言·后端·spring·mvc
码事漫谈12 小时前
AI 读你的提示词,其实很没耐心
后端
用户83562907805112 小时前
如何使用 Python 格式化 Excel 单元格中的长文本
后端·python
我命由我1234512 小时前
Python 开发 - Python 的 pathlib
java·开发语言·后端·python·学习·java-ee·学习方法
IT_陈寒12 小时前
Java性能优化完全指南
前端·人工智能·后端
电子IT笔记12 小时前
对接群晖NAS,上传和删除踩坑记录
前端·后端
Mk5987813 小时前
P4:把 Agent 的记忆搬进 Redis —— AgentScope-Java 工程化实战
后端