最安全的更新方式是 PDO::prepare() + execute(),因其通过预处理语句天然隔离数据与 SQL 逻辑,避免 SQL 注入;而拼接字符串的 mysql_query() 已废弃且极度危险。

直接用 PDO::prepare() + execute() 更新最安全,别拼接 SQL 字符串。
为什么不能用 mysql_query() 拼接字符串更新
老教程里常见 mysql_query("UPDATE user SET name='$name' WHERE id=$id"),现在不仅函数已废弃(PHP 7.0+ 彻底移除),更关键的是——只要 $name 含单引号或 SQL 特殊字符,立刻触发 SQL 注入。比如传入 O'Reilly,生成的 SQL 就会语法错误甚至删库。
- PHP 5.5.0 起
mysql_*系列函数已被弃用 -
mysqli_query()虽可用,但若不配合mysqli_real_escape_string()或预处理,同样危险 - 预处理语句(prepared statement)由数据库引擎解析参数和 SQL 结构,天然隔离数据与逻辑
PDO::prepare() 更新的最小可靠写法
以下代码适用于 MySQL、PostgreSQL、SQLite 等主流 PDO 支持的数据库,只需改 DSN:
$pdo = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
$stmt = $pdo->prepare('UPDATE users SET email = ?, status = ? WHERE id = ?');
$stmt->execute(['user@example.com', 'active', 123]);
注意点:
立即学习“PHP免费学习笔记(深入)”;
- 问号占位符
?顺序必须和execute()数组参数严格一致 - 若要用命名参数,写成
:email、:status,execute()传关联数组:[':email' => '...', ':status' => '...'] - 执行后
$stmt->rowCount()返回受影响行数,可用来判断是否真更新了记录(比如 WHERE 条件没匹配到任何行,返回 0)
更新时字段值为 NULL 或空字符串怎么处理
NULL 值直接传 PHP 的 null,PDO 会正确绑定;空字符串 '' 也照常传,无需额外转义:
$stmt = $pdo->prepare('UPDATE posts SET title = ?, content = ?, published_at = ? WHERE id = ?');
$stmt->execute(['新标题', '', null, 456]);
常见误区:
- 把
null写成字符串'null'→ 数据库存的是字面量 "null",不是 NULL - 对空字符串手动加引号或调用
addslashes()→ 导致存入''或\'\''这类脏数据 - 用
isset()判断字段是否要更新,却忽略empty()对0、'0'、false的误判,建议显式检查array_key_exists()或用默认值兜底
真正容易被忽略的不是语法,而是更新前没验证 WHERE 条件是否精准——比如用用户名更新却没加 AND status != 'deleted',结果误激活了已注销账号;或者批量更新时漏了 LIMIT,一次改了几万条。



















