比如要导入一个大文件, 几M 几十M的文件, 或者在数据库里读取大量数据几万条. 那么这时候是很容易内存溢出,系统崩溃.
解决方案有很多种, 根据不用应用环境来定.可以后台脚本执行,也可以规定限制.
这里介绍一种最常用的的解决策略 : 分批处理
例子一, 这里导入一个几十M的CSV文件. 我们要对里面每条数据进行格式化后再与其他数据匹配等等操作,这些操作要占用大量的内存, 如果一次性读取出来那将是不堪设想的, PHP一个进程里内存有限,在INI文件里 memory_limit = 128M默认是128M. 如果你内存不大,最好不要修改他. 并且已经足够大了. 如果你企望每个进程占用很大的内存,那么你的网站将不会有高负载的能力.
这里每500条处理一次. 分批处理的话就可以充分利用内存而不溢出. 也就是"时间换取空间"的策略:
$handle = fopen($filename, "r");
$container = array();
$index = 0;
$end = false;
if($handle) {
while(true) {
$index++;
$data = fgetcsv($handle, 1000, ",");
// other codes
if(feof($handle)) {
$end = true;
}
if($index >= 500 || $end == true) {
// other codes
$index = 0;
$container = array();
}
if($end) {
break;
}
}
}
fclose($handle);
@unlink($filename);
例子二, 如果要读取数据库里一张表的数据, 如果里面上千万条数据, 一下子都读取到内存里是必死无疑. 如果没有那么多数据也是要优化程序.尽量少占用内存来支持高并发处理.
$totalPage = ceil($testDb->getCount($where) / 500);
for($i = 1; $i <= $totalPage; $i++) {
$list = $testDb->getList($i, 500, $where);
if(count($list) > 0) {
foreach($list as $v) {
// other codes
}
}
}