项目中生成器应用,解决量级数据导出excel内存溢出
admin
2023-07-27 06:40:10
0
应用场景:全量数据导出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']即可。

相关内容

热门资讯

浙江宣传:“走个面儿”咋就没面... “咱北京两千多万人口,您受累,您走个面儿,把这第一波的票房带起来,咱就有了。”某知名导演的新片首映礼...
辞职声明仅95秒遭质疑,韩国队... 【环球时报综合报道】美加墨世界杯小组赛出局后,韩国队主教练洪明甫当地时间28日在墨西哥的韩国队大本营...
美媒爆料:美军第五舰队总部遭伊... 据美国《华尔街日报》27日报道,其通过对卫星图像、社交媒体视频和五角大楼记录的分析发现,今年2月底至...
英国智库给菲律宾GDP增速“浇... 【环球时报特约记者 叶满】英国经济研究机构凯投宏观发布的最新一期《亚洲经济展望》报告(以下简称“报告...
欧洲持续高温,有华人用冰箱降温... 连日来,欧洲多国迎来罕见极端高温天气,法国、德国、意大利等地气温持续飙升,部分地区突破40摄氏度。受...
伊副外长强调船只须按“伊朗线路... 伊朗外交部副部长加里巴巴迪当地时间29日晚间在接受采访时强调,所有船只均须按照“伊朗线路”通过霍尔木...
委内瑞拉强震已致1719人死亡 当地时间29日,委内瑞拉全国代表大会主席罗德里格斯通报,地震已造成该国1719人死亡,5034人受伤...
铋晟新材料申请氯氧化铋基复合材... 国家知识产权局信息显示,江苏铋晟新材料有限公司申请一项名为“一种氯氧化铋基复合材料及其制备方法和用途...
韩国政府将投资千万亿韩元于AI... 韩国总统李在明29日在总统府青瓦台主持召开会议,公布总额超千万亿韩元的半导体、物理人工智能(AI)和...
以色列防长称以伊可能随时再起冲... △卡茨(资料图)据以色列方面29日消息,以国防部长卡茨当天表示,鉴于复杂的安全局势和在黎巴嫩的军事行...