使用Maatwebsite加载Excel遇内存耗尽错误,调整配置后仍无效如何解决?
看到你遇到的内存耗尽错误,我之前也处理过类似的情况,咱们一步步来排查解决:
首先,先明确错误里的关键信息:Allowed memory size of 134217728 bytes exhausted,这就是128MB的内存限制。你修改了config/excel.php里的memoryCacheSize但没效果,大概率是因为PHP本身的内存限制没跟上,或者缓存策略没配置对。
下面是具体的解决步骤:
1. 先提高PHP全局内存限制
Maatwebsite的内存缓存设置是基于PHP允许的最大内存的,如果PHP本身只给128MB,就算excel配置里设了128MB缓存,整体内存还是不够用。
- 先检查当前PHP内存限制:
命令行执行:php -i | grep memory_limit(如果是web环境,就写个phpinfo文件查看),确认输出是不是128MB。 - 修改PHP的内存限制:
找到对应的php.ini文件(注意cli和web环境的php.ini可能不是同一个!如果是用artisan命令处理文件,要改cli版的php.ini),把memory_limit改成更大的值,比如memory_limit = 256M或者512M,具体根据你的文件大小来。 - 重启服务:如果是web环境,重启apache/php-fpm;cli环境的话,修改后直接生效。
2. 切换Maatwebsite的缓存策略到磁盘缓存
默认的内存缓存还是会占用PHP内存,改成磁盘缓存可以把临时数据写到硬盘,大幅降低内存占用:
打开config/excel.php,找到cache配置项,改成:
'cache' => 'disk',
同时可以指定缓存磁盘(比如用local磁盘),修改后记得执行php artisan config:cache生效。
3. 用分块读取优化大文件处理
如果你的Excel文件行数很多,不要一次性加载整个文件,用Maatwebsite的chunk方法分批次处理:
Excel::load('path/to/file.xlsx')->chunk(1000, function ($results) { foreach ($results as $row) { // 处理每一行数据 } });
每次只加载1000行,处理完就释放内存,避免一次性占用大量内存。
4. 手动释放资源避免内存泄漏
处理多个文件时,每个文件处理完后手动清理资源,防止内存堆积:
foreach ($files as $file) { $excel = Excel::load($file); // 你的处理逻辑 // 手动清理资源 $excel->disconnectWorksheets(); unset($excel); gc_collect_cycles(); // 强制触发垃圾回收 }
5. 考虑升级Maatwebsite Excel版本
你现在用的是依赖PHPExcel的老版本(从错误路径里的phpoffice/phpexcel能看出来),PHPExcel已经停止维护,后续的PhpSpreadsheet做了大量内存优化。如果项目允许,升级到Maatwebsite Excel 3.x及以上版本(依赖PhpSpreadsheet),内存占用会比老版本低很多。
按照这些步骤一步步来,应该能解决内存耗尽的问题。
内容的提问来源于stack exchange,提问作者user3242861

