PHP 5.6 中空数组定义不耗内存,但无节制追加数据(如 file_get_contents+json_decode 或循环 $arr[] = $line)会迅速触发内存溢出;应禁用全量加载,改用 fopen()+fgetcsv()/fgets() 流式逐行处理并及时 unset,避免使用生成器(兼容性差),必要时以临时文件或数据库替代内存数组。

在 PHP 5.6 这类旧系统中,定义空数组本身不耗内存,但后续若无节制地往里追加数据(比如 file_get_contents() 后 json_decode() 整个大文件、或循环 $arr[] = $line 累积百万行),就会迅速触发 Allowed memory size exhausted。关键不是“怎么定义空数组”,而是“如何避免它变成内存黑洞”。
别用数组缓存整文件内容
PHP 5.6 没有生成器(yield)的稳定支持(yield 在 PHP 5.5+ 引入但 5.6 中兼容性差、调试困难),所以必须绕开数组累积模式:
- 读 CSV/日志等文本文件时,用
fopen() + fgetcsv() / fgets()流式逐行处理,每行处理完即丢弃,不存入数组 - 禁止写
$lines = file($path)或$data = file_get_contents($path)—— 它们会把整个文件加载进内存 - 若必须结构化暂存,改用临时文件或数据库表替代内存数组,例如处理完一批 1000 行就写入
temp_XXXX.csv,最后合并
初始化数组要带预期容量(仅限已知长度场景)
当确实需要固定大小数组(如解析固定字段的配置块),可用 array_fill(0, $n, null) 预分配,比动态 [] 扩容略省内存(减少内部哈希表重散列):
-
$header = array_fill(0, 10, '');比$header = [];后反复$header[] = ...更可控 - 但此法只适用于长度明确、且不超过几万项的场景;对上传解析类任务基本不适用
上传后立即释放 $_FILES 临时文件引用
PHP 将上传文件暂存为临时文件,$_FILES['file']['tmp_name'] 只是路径字符串,不占多少内存——但开发者常犯错:
立即学习“PHP免费学习笔记(深入)”;
- 错误:读取后不做清理,还反复
file_get_contents($_FILES['file']['tmp_name'])多次 - 正确:调用
move_uploaded_file()成功后,立刻unset($_FILES);若需保留路径,也应$tmp = $_FILES['file']['tmp_name']; unset($_FILES); - 加兜底清理:
register_shutdown_function('unlink', $tmp);防止异常中断导致临时文件堆积
禁用所有调试输出与冗余变量
PHP 5.6 内存管理较弱,var_dump()、print_r()、未 unset 的中间数组极易引发溢出:
- 上传脚本上线前,删除所有
var_dump($huge_array)类语句 - 处理完一行 CSV 后,显式
unset($row);(尤其在长循环中) - 避免使用全局数组缓存,如
$GLOBALS['parsed_rows'][] = $row;—— 这是 PHP 5.6 下最常见泄漏源之一



















