为何mysqli_affected_rows以$link而非查询为参数?相关疑问与示例
为什么mysqli_affected_rows接受链接($link)而非查询作为参数?
这个问题问到点子上了!其实这背后是MySQLi扩展的设计逻辑和对底层MySQL API的沿用决定的,咱们一步步拆解:
核心原因:链接是操作的上下文载体
MySQLi的设计围绕数据库链接展开,不管是面向过程还是面向对象风格,链接都是整个交互的核心:
- 一个数据库链接可以执行多个连续的SQL操作,
mysqli_affected_rows的作用是返回该链接上最近一次执行的SQL操作所影响的行数,而不是绑定到某个特定的查询句柄。 - 有些SQL操作(比如
SET语句、事务的COMMIT/ROLLBACK)不会返回结果集(也就是没有对应的$query句柄),但这些操作可能也会影响数据库状态(比如事务提交后修改的行),用链接作为参数就能覆盖这类场景,不需要依赖查询句柄。 - 另外,MySQLi是对MySQL C API的直接封装,而底层的
mysql_affected_rows()函数就是接收链接句柄的,PHP为了保持和底层API的一致性,沿用了这个参数设计。
mysqli_num_rows 与 mysqli_affected_rows 的示例用法
先明确两者的核心区别:
mysqli_num_rows:针对返回结果集的查询(比如SELECT、SHOW),统计结果集里的行数。mysqli_affected_rows:针对修改数据的操作(比如INSERT、UPDATE、DELETE),统计被操作影响的行数;也支持部分无结果集的操作。
1. mysqli_num_rows 示例(面向过程)
// 建立数据库链接 $link = mysqli_connect('localhost', 'db_user', 'db_pass', 'test_db'); if (mysqli_connect_errno()) { die("链接失败: " . mysqli_connect_error()); } // 执行查询(返回结果集) $userQuery = mysqli_query($link, "SELECT * FROM users WHERE age >= 18"); if (!$userQuery) { die("查询失败: " . mysqli_error($link)); } // 获取结果集行数 $totalUsers = mysqli_num_rows($userQuery); echo "共查询到 {$totalUsers} 名成年用户"; // 释放结果集资源 mysqli_free_result($userQuery); mysqli_close($link);
2. mysqli_affected_rows 示例(面向过程)
$link = mysqli_connect('localhost', 'db_user', 'db_pass', 'test_db'); // 执行更新操作 mysqli_query($link, "UPDATE users SET is_active = 1 WHERE last_login >= '2024-01-01'"); // 获取更新受影响的行数 $updatedCount = mysqli_affected_rows($link); echo "成功激活 {$updatedCount} 名用户"; // 执行删除操作 mysqli_query($link, "DELETE FROM users WHERE is_active = 0 AND created_at < '2023-01-01'"); $deletedCount = mysqli_affected_rows($link); echo "清理了 {$deletedCount} 名长期未活跃用户"; mysqli_close($link);
面向对象风格示例
$mysqli = new mysqli('localhost', 'db_user', 'db_pass', 'test_db'); if ($mysqli->connect_errno) { die("链接失败: " . $mysqli->connect_error); } // mysqli_num_rows 用法 $productResult = $mysqli->query("SELECT * FROM products"); echo "商品总数:" . $productResult->num_rows; $productResult->free(); // mysqli_affected_rows 用法 $mysqli->query("INSERT INTO orders (user_id, total_amount) VALUES (1001, 159.99)"); echo "新增订单数:" . $mysqli->affected_rows; $mysqli->close();
是否让mysqli_affected_rows接收$query作为参数更合理?
这个问题其实是在讨论API设计的权衡,咱们从两个角度看:
支持传$query的合理性
从代码可读性的角度,传$query确实更直观——一眼就能看出来这个受影响行数对应哪个具体的查询,避免了"最近一次操作"可能带来的混淆(比如中间不小心执行了其他操作)。
现有设计的不可替代性
但从MySQLi的整体设计和实用性来看,现有设计更合理:
- 覆盖无查询句柄的场景:像
SET AUTOCOMMIT=0、事务提交这类操作没有返回$query,无法通过$query参数获取受影响行数。 - 减少冗余代码:如果在一个链接里连续执行多个操作,每次都要传递对应的$query,反而会增加代码量;而现在只需要调用
mysqli_affected_rows($link)就能拿到最近一次操作的结果,更简洁。 - 底层API一致性:如前文所说,MySQLi是对MySQL C API的封装,保持参数一致可以降低熟悉底层API开发者的学习成本。
所以综合来看,现有设计是权衡了功能覆盖、代码简洁性和底层兼容性后的选择。
内容的提问来源于stack exchange,提问作者cagri
相关产品推荐
相关产品推荐

