php foreach中一个变量重复赋值是否会不断消耗内存?

                   foreach ($arr as $key => $value) {
                       $res = $this->querydata($value);
                       $data = array('res'=>$res);
                       M('test')->add($data);
                   }
               

如上demo,$res会获取到一个很大的数据,然后存入数据库中,这个foreach循环次数很多,而且每次循环我都没有unset($res),因为我认为重复赋值不会重新消耗内存。。。但好像被打脸,报错了:
图片描述

说超出内存限制128M了。。。请教大神foreach中一个变量的重复赋值会不会一直消耗内存? ( ps: querydata()这个方法有用到curl请求,在这个循环里也就是不断的请求数据)
更新:真实完整代码如下

// 获取到最新分页的酒店id
           $arr = $this->queryHotelIdList();
           if($arr['retrunCode'] == '000'){
               for($i=$play['cur_page'];$i<=$arr['bussinessResponse']['totalPage'];$i++){
                   $page = $i;
                   $arr = $this->queryHotelIdList($page);
                   M('play')->where("id={$play['id']}")->save(array('cur_page'=>$page));

                   // 将1000个id的数组拆分100个10个为一组的二维数组
                   $ten_arr = array_chunk($arr['bussinessResponse']['hotelIds'], 10);
                   // 循环这个二维数组,每一次循环获取10家酒店的基本信息,转json存为一条记录
                   foreach ($ten_arr as $key => $value) {
                       $res = $this->queryHotelInfo($value);
                       if($res['retrunCode'] == '000'){
                           $data = [];
                           $data['page'] = $page;
                           $data['json_data'] = json_encode($res['bussinessResponse']['hotelInfos']);
                           $titan_data_model->add($data);
                           unset($data);

                       }else{
                           // 失败则将这10个酒店id记录下来
                           $failed_ids = implode(',',$value);
                           $data = [];
                           $data['hotel_ids'] = $failed_ids;
                           $data['error_msg'] = $res['retrunMsg'];
                           $data['page'] = $page;
                           $titan_fail_hotel_ids_model->add($data);
                       }
                       unset($res);

                       $memory = memory_get_usage();
                       echo intval($memory/1024);
                       echo "<br>";
                       ob_flush();
                       flush();
                   }
                   
                // 睡眠30秒,以保证不超过300/分钟的请求次数限制
                sleep(30);

               }
            
           }
 里面的queryHotelIdList和queryHotelInfo都是一个封装好的curl请求,返回一个较大的数据,但不会超过1M
阅读 6.4k
4 个回答

前段时间遇到一个无限级分类的问题,为了避免一直消耗内存,赋值过之后的变量就用unset销毁了.

变量重复赋值不会增加内存消耗,当变量被重新赋值为另一个值时,之前的引用计数会被清除,并释放掉相应的内存
然后重新赋值为新的值并分配内存,可能是$res = $this->querydata($value);返回的数据集过大导致超出内存限制
============================更新=========================
看了TP M方法的源码,同一个对象仅会实例化一次不会重复实例化
建议贴完整代码

function M($name='', $tablePrefix='',$connection='') {
    static $_model  = array();
    if(strpos($name,':')) {
        list($class,$name)    =  explode(':',$name);
    }else{
        $class      =   'Think\\Model';
    }
    $guid           =   (is_array($connection)?implode('',$connection):$connection).$tablePrefix . $name . '_' . $class;
    if (!isset($_model[$guid]))
        $_model[$guid] = new $class($name,$tablePrefix,$connection);
    return $_model[$guid];
}

可以使用memory_get_usage();测试一波

新手上路,请多包涵
foreach ($arr as $key => $value) {
    $res = ...
}

没有使用引用,应该不会 导致内存爆。
随便写个测试

$variable = explode(' ', str_repeat('m ', 1024));
$usage = memory_get_usage();
foreach ($variable as $key => $value) {
    $str = str_repeat('k', 1024*1024*50);
}

echo (memory_get_usage() - $usage)/1024/1024 . PHP_EOL;

1024个数组 foreach,每次赋值 给一个变量 50M 的字符串

λ php test.php
52.000022888184
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题