mysqli_prepare() 用于准备一个 SQL 语句,它返回一个 mysqli_stmt 语句对象。例如:
$mysqli = new mysqli("m66.net", "username", "password", "database");
if ($mysqli->connect_error) {
die("连接失败: " . $mysqli->connect_error);
}
$sql = "SELECT * FROM users WHERE email = ?";
$stmt = $mysqli->prepare($sql);
if (!$stmt) {
die("预处理失败: " . $mysqli->error);
}
这里,? 是参数占位符,后续会通过 bind_param 绑定具体值。
mysqli_stmt 对象支持一些属性的获取和设置,允许控制预处理语句的行为。PHP 提供了两个相关方法:
attr_get($attr):获取指定属性的当前值。
attr_set($attr, $value):设置指定属性的值。
例如,MySQLi 支持的属性常量包括:
MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH:控制是否更新最大长度。
MYSQLI_STMT_ATTR_CURSOR_TYPE:设置游标类型(如非游标、只读游标等)。
MYSQLI_STMT_ATTR_PREFETCH_ROWS:预取的行数。
假设我们想使用游标来处理大量数据,避免一次性加载全部结果集,可以设置游标属性:
$sql = "SELECT * FROM large_table WHERE category = ?";
$stmt = $mysqli->prepare($sql);
if (!$stmt) {
die("预处理失败: " . $mysqli->error);
}
// 设置游标类型为 MYSQLI_CURSOR_TYPE_READ_ONLY
$stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_READ_ONLY);
// 绑定参数
$category = 'books';
$stmt->bind_param("s", $category);
$stmt->execute();
// 获取当前游标类型
$currentCursorType = $stmt->attr_get(MYSQLI_STMT_ATTR_CURSOR_TYPE);
echo "当前游标类型是: " . $currentCursorType . PHP_EOL;
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
print_r($row);
}
$stmt->close();
$mysqli->close();
以上示例演示了如何在准备语句后设置游标类型,并用 attr_get() 验证当前属性。
在调用 execute() 之前,尽可能设置所有需要的属性,比如游标类型、预取行数等,确保执行时能够生效。
预处理和属性设置都有可能失败,务必检测返回值,并做好错误处理,避免运行时崩溃。
游标类型会影响内存和性能,尤其在处理大结果集时,使用只读游标(MYSQLI_CURSOR_TYPE_READ_ONLY)通常是更优选择。
某些属性在老版本 MySQL 服务器或 PHP 版本中可能不支持,开发时要确认目标环境的支持情况。
合理结合 mysqli_prepare() 和 mysqli_stmt::attr_get、attr_set,可以让你的数据库操作更灵活高效,同时保持代码的安全性。通过设置合适的属性,尤其是游标和预取行数,可以在处理大数据量时显著优化性能和资源使用。