PHP中Prepare Select预处理语句语法问题求助
PHP 预处理Select语句完全指南(帮你搞定语法错误)
嘿,第一次写预处理语句摸不着头脑太正常了!我刚学的时候也踩过一堆语法坑,别慌,我把两种最常用的PHP数据库扩展(mysqli和PDO)的正确写法拆解给你,再说说最容易踩的坑,保证你能快速搞定。
一、mysqli 扩展写法(面向过程风格)
这是很多新手最先接触的扩展,咱们一步步来:
- 先确保数据库连接正常
// 数据库连接信息 $host = 'localhost'; $dbname = 'your_db'; $username = 'your_user'; $password = 'your_pass'; // 创建连接 $conn = mysqli_connect($host, $username, $password, $dbname); // 检查连接是否成功 if (!$conn) { die("连接失败: " . mysqli_connect_error()); }
- 编写预处理Select语句
核心是把原查询里的变量替换成?占位符,绝对不能给占位符加引号!
比如原查询是SELECT name, email FROM users WHERE id = 123,改成预处理就是:
// 准备预处理语句(?是占位符) $stmt = mysqli_prepare($conn, "SELECT name, email FROM users WHERE id = ?");
- 绑定参数到占位符
这里要注意参数类型:i代表整数,s代表字符串,d代表浮点数,b代表二进制数据。
比如我们要查的id是整数,就这么写:
$user_id = 123; // 你要查询的变量 mysqli_stmt_bind_param($stmt, "i", $user_id);
- 执行语句并获取结果
// 执行预处理语句 mysqli_stmt_execute($stmt); // 获取结果集 $result = mysqli_stmt_get_result($stmt); // 遍历结果 if (mysqli_num_rows($result) > 0) { while ($row = mysqli_fetch_assoc($result)) { echo "用户名: " . $row["name"] . " - 邮箱: " . $row["email"]; } } else { echo "没有找到匹配的记录"; } // 关闭语句和连接 mysqli_stmt_close($stmt); mysqli_close($conn);
二、PDO 扩展写法(更简洁灵活)
PDO支持多种数据库,写法也更优雅,推荐优先用这个:
- 数据库连接
$host = 'localhost'; $dbname = 'your_db'; $username = 'your_user'; $password = 'your_pass'; try { $conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password); // 设置PDO错误模式为异常 $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { die("连接失败: " . $e->getMessage()); }
- 预处理查询(两种方式)
方式1:用?占位符
$user_id = 123; // 准备语句 $stmt = $conn->prepare("SELECT name, email FROM users WHERE id = ?"); // 执行时直接传参数数组 $stmt->execute([$user_id]); // 获取结果 $user = $stmt->fetch(PDO::FETCH_ASSOC); // 单条记录用fetch,多条用fetchAll if ($user) { echo "用户名: " . $user["name"] . " - 邮箱: " . $user["email"]; } else { echo "没有找到匹配的记录"; }
方式2:用命名占位符(更易读)
$user_email = "test@example.com"; $stmt = $conn->prepare("SELECT name, id FROM users WHERE email = :email"); // 绑定参数(可选,也可以直接在execute里传数组) $stmt->bindParam(':email', $user_email); $stmt->execute(); $users = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($users as $user) { echo "ID: " . $user["id"] . " - 用户名: " . $user["name"]; }
三、最容易踩的语法错误坑
- 给占位符加引号:比如写成
WHERE id = '?',这是错的!占位符本身会自动处理引号,不用手动加。 - 参数类型不匹配:比如把字符串类型的邮箱用
i(整数)绑定,会直接报错。 - 忘记执行语句:只写了
prepare但没调用execute,肯定查不到结果。 - mysqli里没获取结果集:用mysqli的时候,执行后必须调用
get_result才能拿到数据,不然直接fetch会失败。
如果你的原查询能正常运行,只需要把原查询中的变量替换成对应的占位符,再绑定参数就OK了,比如原查询是:
SELECT * FROM products WHERE category = '$category' AND price < $max_price
改成预处理就是:
// mysqli版本 $stmt = mysqli_prepare($conn, "SELECT * FROM products WHERE category = ? AND price < ?"); mysqli_stmt_bind_param($stmt, "sd", $category, $max_price);
内容的提问来源于stack exchange,提问作者Neevotic
相关产品推荐
相关产品推荐

