在使用 PHP 操作 MySQL 数据库时,很多开发者习惯用 mysqli 扩展来进行数据库操作。然而,很多人会忽视一个细节:在查询后。你可能会问,$result->free()(或 mysqli_free_result())真的那么重要吗?为什么不能省略?这篇文章就来详细说说。
当你用 mysqli_query() 执行一条查询语句,比如:
$mysqli = new mysqli("localhost", "username", "password", "database");
$result = $mysqli->query("SELECT * FROM users");
这里的 $result 是一个 mysqli_result 对象,里面保存了查询返回的所有数据。它会占用 内存资源,特别是当查询结果很大时,内存消耗就会显著增加。
很多人以为 PHP 是自动管理内存的,脚本结束时会自动清理变量。但事实是:
? 脚本结束时会自动清理内存。
? 但在脚本运行过程中,如果你有多次查询或大查询,不主动释放,内存压力会越来越大。
例如:
for ($i = 0; $i < 1000; $i++) {
$result = $mysqli->query("SELECT * FROM big_table");
// 没有释放结果集
}
上面这段代码,每次循环都会生成一个结果集对象,但没有释放。这会让内存不断攀升,最终可能导致内存溢出或性能急剧下降。
如果加上 $result->free():
for ($i = 0; $i < 1000; $i++) {
$result = $mysqli->query("SELECT * FROM big_table");
$result->free();
}
这样每次循环结束时,结果集占用的内存会被及时释放,大大降低内存使用量。
有两种方法:
1?? 面向对象风格:
$result = $mysqli->query("SELECT * FROM users");
if ($result) {
// 处理结果...
$result->free();
}
2?? 过程化风格:
$result = mysqli_query($mysqli, "SELECT * FROM users");
if ($result) {
// 处理结果...
mysqli_free_result($result);
}
注意:如果查询失败(返回 false),调用 free() 会报错,所以要先判断 $result 是否为有效对象。
短小的脚本、单次查询,你可能感觉不到差异。但在这些场景下,不释放结果集会有严重后果:
大数据量查询: 查询几万、几十万行时,结果集占用的内存非常大。
长时间运行的脚本: 比如定时任务、爬虫、守护进程。
高并发 Web 服务: 每个请求都耗内存,长久下来拖垮服务器。
在这些情况下,不释放结果集,轻则拖慢应用,重则让服务器崩溃。
记住一句话:用完的资源必须手动释放!
即使 PHP 会自动回收内存,也不要依赖它来管理运行中的资源。
在实际开发中,养成良好的习惯——查询后及时 $result->free(),不仅是写“对”的代码,更是写“好”的代码。