• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

php导出超大csv导出方法,读取超大文件或者接受超大数组,防止内存溢出 ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

基本思路就是,知道总数之后分割成2万一个数组进行查询,最后独立写入csv,避免数据过大导致溢出

速度还不错,在php7下,机器I5 8G内存,128G,SSD,52W多条,大概也就30秒,出来整个文件38.2M

$per = 10000; 37秒

$per = 20000; 34秒

$per = 30000; 的时候速度最快29秒左右

$per = 40000;30-31秒

所以建议在30000步幅,比较好,我的环境是windows 32位,64位或许会更好

建议导入文件过多就zip压缩之后再下载

 

laravel 写的demo  2018年6月19日18:13:26

  $start = time();
        set_time_limit(0);
        ini_set('memory_limit', '512M');
        //获取总数
        $count = DataChinaYearData::count();
        //526672
        $per = 30000;

        $section = array();
        for ($i = 0; $i <= $count; $i += $per) {
            $section[] = $i;
        }
        if (end($section) < $count) {
            $section[] = $count;
        }
        //清理输出流的防止乱码
        ob_flush();
        flush();
        $fp = fopen('file.csv', 'w');

        foreach ($section as $k => $v) {
            $list = array();
            $list = DataChinaYearData::offset($v)->limit($per)->get()->toArray();
            foreach ($list as $fields) {
                fputcsv($fp, $fields);
            }
            unset($list); //防止溢出
            ob_flush();
            flush();
        }
        fclose($fp);
        $end = time();

        $time = $end - $start;
        echo $time . '秒';

 

 

 

另一种懒人写法,全部使用迭代器去操作

 $start = time();
        set_time_limit(0);

        $fp = fopen('file.csv', 'w');
        foreach (new \ArrayObject(DataChinaYearData::get()->toarray()) as $k => $v) {
            fputcsv($fp, $v);
        }
        fclose($fp);
        $end = time();
        $time = $end - $start;
        echo $time . '秒';

原理也很简单,pdo就是迭代器,直接使用数组迭代器赋值,不使用变量接收就不会内存溢出

测试了2次,39秒和40秒,显然这样的速度就慢了一些,可以通过逻辑优化的就使用逻辑优化,纯靠语言特性优化有时候是方便了写代码但是代码思维逻辑就差多了

 

也可以通过使用迭代器接受超大数组,比如我需要读取一个2G或者更大的文本文件或者excel,我直接按行读取,然后全部放入迭代器中这样不会出现内存溢出的情况

伪demo,有时间在写个实际的demo

public static function test() {
        pp(self::get_array() instanceof \Generator);
        pp(self::get_array());
        /*
         * Generator Object
          (
          )
         * 
         */
        foreach (self::get_array() as $k => $v) {
            p($k);
            p($v);
        }
    }

    public static function get_array() {
        $rr = array('0' => array('a' => 'aa'), '1' => array('a' => 'bb'), '2' => array('c' => 'cc'), '3' => array('d' => 'dd'));
//        $rr = array('0' => 'a', '1' => 'b', '2' => 'c', '3' => 'd');

        foreach ($rr as $k => $v) {
            yield $k => $v;
        }
    }

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Ubuntu源码安装Apache2.2.19+Mysql-5.5.16+Php-5.3.8+PDO+Pure-Ftpd服务命令发布时间:2022-07-10
下一篇:
php无限参数方法发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap