侧边栏壁纸
博主头像
云BLOG 博主等级

行动起来,活在当下

  • 累计撰写 318 篇文章
  • 累计创建 6 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录
SQL

Thinkphp8 DB构建和链式调用

Administrator
2025-09-25 / 0 评论 / 0 点赞 / 1 阅读 / 0 字

一、为什么链式调用是安全的?

ThinkPHP 的查询构建器会对所有传入的参数进行参数绑定(预处理),而非直接拼接 SQL 字符串。例如:

php

// 安全:框架会自动参数绑定
Db::name('user')->where('id', $id)->select();

// 生成的 SQL 类似:SELECT * FROM `user` WHERE `id` = :id 
// 参数 :id 会通过 PDO 预处理机制传入,避免注入

危险行为:直接拼接 SQL 字符串(需绝对避免)

php

// 不安全!存在注入风险
Db::query("SELECT * FROM user WHERE id = " . $id);

二、查询构建器的基本用法(防注入)

以下是增删查改的标准用法,均基于查询构建器实现,自带防注入保护:

1. 查(查询数据)

php

// 1.1 单条数据
$user = Db::name('user')
    ->where('id', $id)
    ->find(); // 返回一条记录

// 1.2 多条数据
$list = Db::name('user')
    ->where('status', 1)
    ->where('create_time', '>=', $startTime)
    ->order('id', 'desc')
    ->limit(10)
    ->select(); // 返回数组

// 1.3 分页查询
$page = Db::name('user')
    ->where('status', 1)
    ->order('id', 'desc')
    ->paginate([
        'list_rows' => 10, // 每页条数
        'page' => 1 // 当前页
    ]);
$total = $page->total(); // 总记录数
$items = $page->items(); // 当前页数据

// 1.4 聚合查询
$count = Db::name('user')->where('status', 1)->count(); // 计数
$maxId = Db::name('user')->max('id'); // 最大值

2. 增(新增数据)

php

// 2.1 单条插入
$data = [
    'name' => '张三',
    'age' => 20,
    'create_time' => time()
];
$insertId = Db::name('user')->insertGetId($data); // 返回新增ID
// 或
$affected = Db::name('user')->insert($data); // 返回影响行数

// 2.2 批量插入
$list = [
    ['name' => '张三', 'age' => 20],
    ['name' => '李四', 'age' => 22]
];
$affected = Db::name('user')->insertAll($list); // 返回插入总数

3. 改(更新数据)

php

// 3.1 更新单条/多条
$affected = Db::name('user')
    ->where('id', $id)
    ->update([
        'name' => '新名称',
        'update_time' => time()
    ]); // 返回影响行数

// 3.2 自增/自减
Db::name('user')->where('id', $id)->inc('age', 1)->update(); // 年龄+1
Db::name('user')->where('id', $id)->dec('score', 10)->update(); // 分数-10

4. 删(删除数据)

php

// 4.1 删除单条/多条
$affected = Db::name('user')
    ->where('id', $id)
    ->delete(); // 返回影响行数

// 4.2 清空表(谨慎使用)
Db::name('user')->truncate(); // 清空表,无返回值

三、复杂查询条件的安全写法

1. 多条件查询

php

// 方式1:多次调用 where
Db::name('user')
    ->where('status', 1)
    ->where('age', '>', 18)
    ->select();

// 方式2:数组条件(推荐,更清晰)
Db::name('user')
    ->where([
        ['status', '=', 1],
        ['age', '>', 18],
        ['create_time', 'between', [$start, $end]]
    ])
    ->select();

2. 带 OR 的条件

php

Db::name('user')
    ->where('status', 1)
    ->whereOr('age', '<', 18) // OR 条件
    ->select();

3. 字段筛选(避免查询敏感字段)

php

// 只查询指定字段
Db::name('user')->field('id, name, age')->select();

// 排除敏感字段
Db::name('user')->field('password', true)->select(); // 排除 password 字段

四、总结

  1. 推荐用法:始终使用 Db::name('table') 链式调用,框架会自动防注入。

  2. 避免行为:禁止直接拼接 SQL 字符串(如 Db::query("SELECT * FROM user WHERE id = $id"))。

  3. 复杂场景:即使是多条件、OR 逻辑、批量操作,只要通过查询构建器的方法实现,均能保证安全。

ThinkPHP 的查询构建器已对 SQL 注入做了完善处理,遵循上述用法即可安全操作数据库。

0

评论区