Allowed memory size of xxx bytes exhausted

  • 问题描述
  • 解决方法
    • 修改php.ini文件对应的配置项
    • 代码中动态修改这个值的大小
    • php 的生成器 yield
      • 代码如下

问题描述

当一次获取大量数据的时候,导致php的内存溢出。
准确的说,是超出了php.ini文件设置的脚本可能消耗的最大内存量。如下图
在这里插入图片描述

解决方法

修改php.ini文件对应的配置项

上图 memory_limit = 128M 就是 脚本可能消耗的最大内存量,可以适当加大这个值。

代码中动态修改这个值的大小

另外你可能还要设置脚本的超时时间来配合使用。

1
2
set_time_limit(0);//设置脚本执行时间 不超时
ini_set(‘memory_limit’, ‘512M’);

php 的生成器 yield

 

 

当修改 memory_limit 的次数越来越频繁,这个值越来越大。
你开始怀疑,把这个值改成多大都不行,因为数据量越来越大,内存总有耗尽的时候。
你可能想到减少一次获取到的数据量,比如在导出数据的时候,可以分批获取数据。
但是有更简单的方法。且更重要的是,你不必再担心脚本内存的耗尽。哪怕你一次获取全部数据。

代码如下

如果你自己封装过一个模型,用来一次获取结果集中的所有记录数,下面的代码你肯定很熟悉。此函数用来获取结果集中的所有记录数。

1
2
3
4
5
6
7
8
9
10
//省略了部分代码,看你悟性了 ^ ^
function fetchAll($sql){
    //$this->link 保存的是数据库的连接句柄
    $result=mysqli_query($this->link,$sql);
    $rows = array();
    while($row = mysqli_fetch_array($result,MYSQLI_ASSOC)){
        $rows[]=$row;
    }
    return $rows;
}

只需要简单修改一下这个函数就能解放你的内存。

1
2
3
4
5
6
7
8
9
10
//修改后的函数
function fetchAll($sql){
    //$this->link 保存的是数据库的连接句柄
    $result=mysqli_query($this->link,$sql);
    $num = 0;//用作key
    while($row = mysqli_fetch_array($result,MYSQLI_ASSOC)){
        yield $num => $row;//这里是关键
        $num ++;
    }
}