应用场景:全量数据导出excel遇到问题:

PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 41007872 bytes)

很明显是内存溢出。

网上给出了很多治标不治本的解决方案:

1.直接修改PHP.INI
memory_limit = xxxx M ;
2.修改.htaccess
php_value memory_limit xxx M
3.直接在程序页面上修改。
ini_set(‘memory_limit’, ‘xxx M);

上述方案都是通过调整内存大小限制,没法解决根本问题。达到更高一量级的数据,内存肯定不够用。

救星来了,生成器。

请看代码:

$list = function () use ($result, $areaList, $industryList, $channelList, $useStatusList, $billServiceFollow, $serviceOrderAmount, $statistics, $adminUserInfo, $implementerInfo, $salesInfo) { foreach ($result as $value) { $value['province_name'] = $areaList[$value['province_id']] ?? '无';//省份 $value['city_name'] = $areaList[$value['city_id']] ?? '无';//城市 $industry = $value['industry'] ?? 0; $value['industry_name'] = $industryList[$industry] ?? '无';//行业 $channel = $value['channel'] ?? 0; $value['channel_name'] = $channelList[$channel] ?? '无';//客户来源 $useStatus = $value['use_status']; $value['contract_type'] = $useStatusList[$useStatus] ?? '';//合同类型 if ($useStatus == 1) {//正式合同 $startTime = $value['formal_starttime'] ?? 0; if ($startTime == '0000-00-00 00:00:00') { $startTime = 0; } $endTime = $value['formal_endtime'] ?? 0; if ($startTime == '0000-00-00 00:00:00') { $endTime = 0; } $value['contract_begin_date'] = !empty($startTime) ? date('Y-m-d', strtotime($startTime)) : '无'; $value['contract_end_date'] = !empty($endTime) ? date('Y-m-d', strtotime($endTime)) : '无'; } else {//试用合同 $startTime = $value['tryout_starttime'] ?? 0; if ($startTime == '0000-00-00 00:00:00') { $startTime = 0; } $endTime = $value['tryout_endtime'] ?? 0; if ($startTime == '0000-00-00 00:00:00') { $endTime = 0; } $value['contract_begin_date'] = !empty($startTime) ? date('Y-m-d', strtotime($startTime)) : '无'; $value['contract_end_date'] = !empty($endTime) ? date('Y-m-d', strtotime($endTime)) : '无'; } $value['acenum'] = $statistics[$value['id']]['acenum'] ?? 0;//账套数量 $value['usernum'] = $statistics[$value['id']]['usernum'] ?? 0;//会计数量 $value['vounum'] = $statistics[$value['id']]['vounum'] ?? 0;//凭证 $value['billnum'] = $statistics[$value['id']]['billnum'] ?? 0;//上传票据 //购买票据数量 $totalServiceNum = $billServiceFollow[$value['id']]['total_service_num'] ?? 0; if ($totalServiceNum >= 100000000) { $totalServiceNum = '不限量'; } $value['total_service_num'] = $totalServiceNum; //成交金额 $value['total_recive_amount'] = $serviceOrderAmount[$value['id']]['total_recive_amount'] ?? 0; $value['create_by_name'] = $adminUserInfo[$value['create_by']] ?? '无'; //实施名称 $implementer = $value['implement'] ?? 0; $value['implementer'] = $implementerInfo[$implementer] ?? '无'; //销售 $sale = $value['sale_id'] ?? 0; $value['sale'] = $salesInfo[$sale] ?? '无'; $abutment = $value['abutment'] ?? 0; $value['abutment'] = $salesInfo[$abutment] ?? '无'; yield $value; } }; $data['list'] = $list(); //调用下载excel $excel = new DownloadExcel(); return $excel->title('客户列表')->subtitle('')->subject('')->fill('company-list', $data)->download();解决问题:

内存溢出

知识点说明:

1.将大结果集的数据单元yield,传给生成器。
2.通过function()use{};匿名函数接收生成器作为结果。

$data['list'] = $list();

后续只需要迭代$data['list']即可。