PHP mysqli代码转Prepared Statements预处理语句求助
嘿,我太懂把旧的mysqli代码改成预处理语句时那种碰壁的挫败感——我当初第一次转的时候也踩了一堆莫名其妙的坑!别着急,咱们先从最基础的正确流程拆解,再聊聊你大概率忽略的细节,帮你把坑填上。
首先,一定要开启mysqli的错误报告!这是很多人踩坑的根源——默认情况下mysqli会静默错误,你根本不知道代码到底哪里炸了。先把这行代码加在连接数据库之前:
// 强制mysqli抛出错误,帮你快速定位问题 mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
先给你两个最常用场景的完整示例
场景1:查询单条数据(比如根据ID查用户)
假设你原来的非预处理代码是这样:
// 旧写法(有SQL注入风险) $result = $conn->query("SELECT name, email FROM users WHERE id = " . $_GET['id']); $user = $result->fetch_assoc();
改成预处理语句的正确写法:
// 1. 建立连接(记得加错误报告和字符集) mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); $conn = new mysqli('localhost', '你的用户名', '你的密码', '数据库名'); $conn->set_charset('utf8mb4'); // 必须设置,避免乱码和字符集注入 // 2. 准备预处理语句,用?做占位符 $userId = $_GET['id']; $stmt = $conn->prepare("SELECT name, email FROM users WHERE id = ?"); // 3. 绑定参数:"i"表示整数类型,对应后面的$userId // 类型符规则:i=整数,s=字符串,d=浮点数,b=二进制数据 $stmt->bind_param("i", $userId); // 4. 执行语句 $stmt->execute(); // 5. 获取结果(两种可选方式) // 方式A:绑定结果到变量(兼容性好) $stmt->bind_result($name, $email); if ($stmt->fetch()) { echo "用户名:$name,邮箱:$email"; } else { echo "没找到该用户"; } // 方式B:用get_result(需要mysqlnd扩展支持,更灵活,能直接用fetch_assoc) // $result = $stmt->get_result(); // $user = $result->fetch_assoc(); // if ($user) { // echo "用户名:{$user['name']},邮箱:{$user['email']}"; // } // 6. 关闭语句 $stmt->close();
场景2:插入/更新数据(比如新增用户)
旧写法可能是这样:
// 旧写法(风险极高) $conn->query("INSERT INTO users (name, email) VALUES ('$name', '$email')");
预处理写法:
$name = "张三"; $email = "zhangsan@example.com"; $stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (?, ?)"); // 两个参数都是字符串,所以用"ss" $stmt->bind_param("ss", $name, $email); $stmt->execute(); // 获取插入后的自增ID echo "新增用户ID:" . $stmt->insert_id; $stmt->close();
你大概率踩过的坑,避坑指南
- 占位符不能加引号:比如写
WHERE email = '?'是错的,直接写WHERE email = ?就行,预处理会自动处理引号和转义。 - bind_param的类型符要匹配:如果把字符串用
i(整数)绑定,或者反过来,都会导致执行失败。 - 执行后要正确获取结果:如果想用
$stmt->num_rows,必须先调用$stmt->store_result()或者get_result(),不然会得到0。 - 不要重复使用未重置的stmt:如果要复用同一个stmt执行不同参数,记得先调用
$stmt->reset()。
如果你把之前尝试的代码片段贴出来,咱们能更精准地定位问题!不过先试试开启错误报告,大概率能直接看到报错原因,瞬间解决问题~
内容的提问来源于stack exchange,提问作者RvN-
相关产品推荐
相关产品推荐

