相信很多人做大批量数据导出和数据导入的时候,经常会遇到PHP内存溢出的问题,在解决了问题之后,总结了一些经验,整理成文章记录下。

优化点
1、优化SQL语句,避免慢查询,合理的建立索引,查询指定的字段,sql优化这块在此就不展开了。
2、查询的结果集为大对象时转数组处理,框架中一般有方法可以转,如Laravel中有toArray(),Yii2中有asArray()。
3、对于大数组进行数据切割处理,PHP函数有array_chunk()、array_slice()。
对于大型的字符串和对象,使用引用传递&。
4、用过的变量及时unset。
5、导出的文件格式由excel改为csv
6、ini_set(‘memory_limit’,’’),设置程序可以使用的内存(不建议这样做)。

思考

内存管理
PHP的内存什么怎么管理的呢? 在学C语言时,开发者是需要手动管理内存。在PHP中,Zend引擎提供为了处理请求相关数据提供了一种特殊的内存管理器。请求相关数据是只需要服务单个请求,最迟会在请求结束时释放数据。


防止内存泄漏并尽可能快地释放所有内存是内存管理的重要组成部分。因为安全原因,Zend引擎会释放所有上面提到的API锁分配的内存。

垃圾回收机制

简单说下:

PHP5.3之前,采用引用计数的方式管理。PHP中的变量存在zval的变量容器中,变量被引用的时,引用计数+1,变量引用计数为0时,PHP将在内存中销毁这个变量。但是在引用计数循环引用时,引用计数就不会消减为0,导致内存泄漏。

PHP5.3之后做了优化,并不是每次引用计数减少都进入回收周期,只有根缓冲区满额后才开始进行垃圾回收,这样可以解决循环引用的问题,也可以将总内存泄漏保持在一个阈值之下。

代码

由于使用phpexcel时经常会遇到内存溢出,下面分享一段生成csv文件的代码:

<?phpnamespace api\service;class ExportService
{public static $outPutFile = '';/*** 导出文件* @param string $fileName* @param $data* @param array $formFields* @return mixed*/public static function exportData($fileName = '', $data, $formFields = []){$fileArr = [];$tmpPath = \Yii::$app->params['excelSavePath'];foreach (array_chunk($data, 10000) as $key => $value) {self::$outPutFile = '';$subject          = !empty($fileName) ? $fileName : 'data_';$subject          .= date('YmdHis');if (empty($value) || empty($formFields)) {continue;}self::$outPutFile = $tmpPath . $subject . $key . '.csv';if (!file_exists(self::$outPutFile)) {touch(self::$outPutFile);}$index  = array_keys($formFields);$header = array_values($formFields);self::outPut($header);foreach ($value as $k => $v) {$tmpData = [];foreach ($index as $item) {$tmpData[] = isset($v[$item]) ? $v[$item] : '';}self::outPut($tmpData);}$fileArr[] = self::$outPutFile;}$zipFile = $tmpPath . $fileName . date('YmdHi') . '.zip';$zipRes = self::zipFile($fileArr, $zipFile);return $zipRes;}/*** 向文件写入数据* @param array $data*/public static function outPut($data = []){if (is_array($data) && !empty($data)) {$data = implode(',', $data);file_put_contents(self::$outPutFile, iconv("UTF-8", "GB2312//IGNORE", $data) . PHP_EOL, FILE_APPEND);}}/*** 压缩文件* @param $sourceFile* @param $distFile* @return mixed*/public static function zipFile($sourceFile, $distFile){$zip = new \ZipArchive();if ($zip->open($distFile, \ZipArchive::CREATE) !== true) {return $sourceFile;}$zip->open($distFile, \ZipArchive::CREATE);foreach ($sourceFile as $file) {$fileContent = file_get_contents($file);$file        = iconv('utf-8', 'GBK', basename($file));$zip->addFromString($file, $fileContent);}$zip->close();return $distFile;}/*** 下载文件* @param $filePath* @param $fileName*/public static function download($filePath, $fileName){if (!file_exists($filePath . $fileName)) {header('HTTP/1.1 404 NOT FOUND');} else {//以只读和二进制模式打开文件$file = fopen($filePath . $fileName, "rb");//告诉浏览器这是一个文件流格式的文件Header("Content-type: application/octet-stream");//请求范围的度量单位Header("Accept-Ranges: bytes");//Content-Length是指定包含于请求或响应中数据的字节长度Header("Accept-Length: " . filesize($filePath . $fileName));//用来告诉浏览器,文件是可以当做附件被下载,下载后的文件名称为$file_name该变量的值Header("Content-Disposition: attachment; filename=" . $fileName);//读取文件内容并直接输出到浏览器echo fread($file, filesize($filePath . $fileName));fclose($file);exit();}}
}

调用处代码

$fileName = "库存导入模板";
$stockRes = []; // 导出的数据
$formFields = ['store_id'  => '门店ID','storeName' => '门店名称','sku'       => 'SKU编码','name'      => 'SKU名称','stock'     => '库存','reason'    => '原因'
];
$fileRes    = ExportService::exportData($fileName, $stockRes, $formFields);
$tmpPath    = \Yii::$app->params['excelSavePath']; // 文件路径
$fileName   = str_replace($tmpPath, '', $fileRes);// 下载文件
ExportService::download($tmpPath, $fileName);

以上内容希望帮助到大家,更多免费PHP大厂PDF,PHP进阶架构视频资料,PHP精彩好文可以微信搜索关注:PHP开源社区

2021金三银四大厂面试真题集锦,必看!

四年精华PHP技术文章整理合集——PHP框架篇

四年精华PHP技术文合集——微服务架构篇

四年精华PHP技术文合集——分布式架构篇

四年精华PHP技术文合集——高并发场景篇

四年精华PHP技术文章整理合集——数据库篇

PHP内存溢出是什么样的相关推荐

  1. Tomcat内存溢出解决方法

    Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出 JVM在 ...

  2. 深入理解Java虚拟机——第二章——Java内存区域与内存溢出异常

    运行时数据区域 Java虚拟机运行时数据区域 程序计数器 程序计数器可以看做是当前线程所执行的字节码的行号指示器.字节码解释器工作时就是通过改变这个计数器的值来选取下一条所需要执行的字节码指令,分支. ...

  3. Java内存溢出详解之Tomcat配置

    Java内存溢出详解 转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError ...

  4. 解决Mask RCNN训练时GPU内存溢出问题

    首先自己是个小白对于如何使用GPU跑程序这个学习了一下: (1)使用的是putty,安装了Anaconda这个IDE环境,用的conda install tensorflow-gpu安装的GPU版本t ...

  5. 内存溢出和内存泄漏的定义,产生原因以及解决方法(面试经验总结)

    一.定义(概念与区别) 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory:比如申请 了一个integer,但给它存了long才能存 ...

  6. 从内存溢出看Java 环境中的内存结构

    作为有个java程序员,我想大家对下面出现的这几个场景并不陌生,倍感亲切,深恶痛绝,抓心挠肝,一定会回过头来问为什么为什么为什么会这样,嘿嘿,让我们看一下我们日常在开发过程中接触内存溢出的异常: Ex ...

  7. JVM内存溢出的几种情形

    1.堆溢出 原因:大量对象占据了堆空间,而这些对象都有强引用导致无法回收,当对象大小之和>Xmx参数指定的堆大小时导致溢出! List<byte[]> list = new Arra ...

  8. python会不会出现内存泄露_Python内存泄漏和内存溢出的解决方案

    一.内存泄漏 像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题. 对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是 ...

  9. 小编带你进入强如 Disruptor 也发生内存溢出?

    前言 OutOfMemoryError 问题相信很多朋友都遇到过,相对于常见的业务异常(数组越界.空指针等)来说这类问题是很难定位和解决的. 本文以最近碰到的一次线上内存溢出的定位.解决问题的方式展开 ...

  10. Visual C++ 2012/2013的内存溢出检測工具

    在过去,每次编写C/C++程序的时候,VLD差点儿是我的标配.有了它,就能够放心地敲代码,随时发现内存溢出. VLD最高可支持到Visual Studio 2012.不知道以后会不会支持Visual ...

最新文章

  1. NOIP2018TG 初赛复习
  2. 爬取及分析天猫商城冈本评论(二)数据处理
  3. 高级数据结构与算法 | B树、B+树、B*树
  4. [Java基础]Stream流终结操作之forEachcount
  5. 接口测试客户端的搭建
  6. max file descriptors_年轻族的战场!宋MAX强势对比嘉际
  7. [JAVA]全新java初学者实践教程(全)
  8. DevOps使用教程 华为云(6)文档报告 项目进度 会议记录 迭代评审
  9. Java 定时任务@Scheduled使用
  10. 连接摄像头拍照并识别图片中二维码
  11. python 取数组最后一个_在numpy数组中查找最后一个值
  12. Progressive LayeredExtraction(PLE):ANovelMulti-Task Learning(MTL)ModelforPersonalizedRecommendations
  13. 算法证明题 8.9 HITTING SET
  14. java队列处理高并发_Java高并发--消息队列
  15. 负债均衡,反向代理以及常见的分发策略
  16. 西门子S7-200的VB、VW和VD
  17. 小米2018春招实习笔试题总结
  18. 淘淘商城的第一天(传智播客2015年9月份项目)
  19. 跑了1135家制造企业 它们是怎么把自己玩死的了
  20. 上海电力学院计算机辅助设计2,上海电力学院电路计算机辅助设计2--正弦激励下的RL一阶电路的响应...

热门文章

  1. 10.每天进步一点点---Python-Requests HTTP 请求库-2
  2. 冥王峡谷黑苹果之苹果网卡转接板选择分析
  3. 【智能优化算法】基于文化和谐和学习算法优化模糊函数FUZZY附matlab代码
  4. C++ 打怪小游戏3.1
  5. 美联致美, 专属定制之美,让美丽不可复制
  6. 怎么做消防安全知识教育培训PPT课件?
  7. PC寄存器 -- 读书摘抄
  8. 十个最火的HTML5框架与移动应用框架的比较
  9. 假如你是微信安卓端测试人员,针对微信发送消息这个功能,你会如何设计测试用例?
  10. PS 滤镜——素描算法(二)