項目中生成器應用,解決量級數據導出excel內存溢出
阿新 • • 發佈:2018-09-10
pre 解決 load title use 方案 locate 省份 admin 應用場景:全量數據導出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‘]即可。
項目中生成器應用,解決量級數據導出excel內存溢出