应用场景: 全量数据导出 excel
遇到问题:
PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 41007872 bytes)
很明显是内存溢出.
网上给出了很多治标不治本的解决方案:
1. 直接修改 PHP.INI
memorylimit = xxxx M ;
2. 修改. htaccess
phpvalue memorylimit xxx M
3. 直接在程序页面上修改.
iniset('memorylimit', 'xxx M);
上述方案都是通过调整内存大小限制, 没法解决根本问题. 达到更高一量级的数据, 内存肯定不够用.
救星来了, 生成器.
请看代码:
- $list = function () use ($result, $areaList, $industryList, $channelList, $useStatusList, $billServiceFollow, $serviceOrderAmount, $statistics, $adminUserInfo, $implementerInfo, $salesInfo) {
- foreach ($result as $value) {
- $value['provincename'] = $areaList[$value['provinceid']] '无';// 省份
- $value['cityname'] = $areaList[$value['cityid']] '无';// 城市
- $industry = $value['industry'] 0;
- $value['industryname'] = $industryList[$industry] '无';// 行业
- $channel = $value['channel'] 0;
- $value['channelname'] = $channelList[$channel] '无';// 客户来源
- $useStatus = $value['usestatus'];
- $value['contracttype'] = $useStatusList[$useStatus] '';// 合同类型
- if ($useStatus == 1) {// 正式合同
- $startTime = $value['formalstarttime'] 0;
- if ($startTime == '00000000 00:00:00') {
- $startTime = 0;
- }
- $endTime = $value['formalendtime'] 0;
- if ($startTime == '00000000 00:00:00') {
- $endTime = 0;
- }
- $value['contractbegindate'] = !empty($startTime) date('Ymd', strtotime($startTime)) : '无';
- $value['contractenddate'] = !empty($endTime) date('Ymd', strtotime($endTime)) : '无';
- } else {// 试用合同
- $startTime = $value['tryoutstarttime'] 0;
- if ($startTime == '00000000 00:00:00') {
- $startTime = 0;
- }
- $endTime = $value['tryoutendtime'] 0;
- if ($startTime == '00000000 00:00:00') {
- $endTime = 0;
- }
- $value['contractbegindate'] = !empty($startTime) date('Ymd', strtotime($startTime)) : '无';
- $value['contractenddate'] = !empty($endTime) date('Ymd', 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']]['totalservicenum'] 0;
- if ($totalServiceNum>= 100000000) {
- $totalServiceNum = '不限量';
- }
- $value['totalservicenum'] = $totalServiceNum;
- // 成交金额
- $value['totalreciveamount'] = $serviceOrderAmount[$value['id']]['totalreciveamount'] 0;
- $value['createbyname'] = $adminUserInfo[$value['createby']] '无';
- // 实施名称
- $implementer = $value['implement'] 0;
- $value['implementer'] = $implementerInfo[$implementer] '无';
- // 销售
- $sale = $value['saleid'] 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('companylist', $data)>download();
解决问题:
内存溢出
知识点说明:
1. 将大结果集的数据单元 yield, 传给生成器.
2. 通过 function()use{}; 匿名函数接收生成器作为结果.
$data['list'] = $list();
后续只需要迭代 $data['list'] 即可.
来源: http://www.bubuko.com/infodetail-2762347.html