当我们执行多条插入操作或在事务中插入数据时,直接通过 mysqli->insert_id 读取自增 ID 可能会不准确,尤其是在多线程或多用户并发访问时。使用预处理语句的 $insert_id 属性,可以确保获得当前语句影响的插入 ID。
mysqli_stmt::$insert_id 是在 PHP 8.1 及以后版本中新增的属性,专门用于获取执行预处理语句后的自增 ID,相比 $mysqli->insert_id 更加精确和安全。
以下示例演示了如何在事务中使用 mysqli_stmt 执行插入操作,并获取插入记录的 ID:
<?php
$mysqli = new mysqli("gitbox.net", "username", "password", "database");
// 开启事务
$mysqli->begin_transaction();
try {
// 预处理插入语句
$stmt = $mysqli->prepare("INSERT INTO users (username, email) VALUES (?, ?)");
$username = 'alice';
$email = '[email protected]';
$stmt->bind_param("ss", $username, $email);
// 执行插入
$stmt->execute();
// 获取插入的 ID
$insertId = $stmt->insert_id;
echo "新插入用户的ID是: " . $insertId . "\n";
// 提交事务
$mysqli->commit();
$stmt->close();
} catch (Exception $e) {
// 发生错误回滚事务
$mysqli->rollback();
echo "事务失败,已回滚。错误信息: " . $e->getMessage();
}
$mysqli->close();
?>
在事务中执行插入操作时,先调用 $mysqli->begin_transaction() 开启事务,操作结束后调用 $mysqli->commit() 提交,失败则调用 $mysqli->rollback() 回滚。
使用 mysqli_stmt 预处理语句执行插入,避免 SQL 注入风险。
插入成功后,通过 $stmt->insert_id 获取本次插入的自增 ID,确保准确无误。
异常处理中一定要回滚事务,保证数据的一致性和完整性。
mysqli_stmt::$insert_id 仅在 PHP 8.1 及以上版本可用。如果使用的是旧版本 PHP,可以考虑用 $mysqli->insert_id,但要注意并发问题。