• 生成器来解决大文件读取,大数据下载


    场景

    电商平台想要导出一年的报表数据,数据可能有百万,平常的做法是查出所有数据放到数组或对象中,再进行excel导出,一般情况下,数据不是很多这种是没什么问题,但百万级别的数据一下读到内存中,服务器会一下崩溃,内存溢出。通常情况下也不会做这种需求,产品提出来你可以骂两句怼回去,但老板说我就需要这个功能,你苦口婆心说几句,但是还是要做啊。生成器可以帮我做到这些,理解概念可以看看这里

    下载文件

      //实现下载大文件,解决内存溢出
        public function actionExport(){
    
            $filename =  'sun.csv'; //设置文件名
            header('Content-Type: text/csv');
            header("Content-Disposition: attachment;filename={$filename}");
    
            $fp = fopen('php://output', 'w');
    
            $sql = 'select * from "SCM_tbIOStockDtl"';
    
            //非迭代器实现  十万多条数据,导出csv服务器直接崩溃,内存溢出
    //        $list = Yii::$app->db->createCommand($sql)->queryAll();
    
            //PDO::query() 本身由迭代器实现
            $pdo = new PDO('pgsql:host=192.168.33.30;port=5432;dbname=jump', 'postgres', '123456');
            $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
            $list = $pdo->query($sql);
    
            foreach ( $list  as  $fields ) {
                fputcsv ( $fp ,  $fields );
            }
    
            fclose ( $fp );
        }
    

    读取大文件

      //读取大文件
        public function actionRead(){
    
            $result = $this->readCsv(Yii::$app->basePath.'/web/file/sun.csv');
    
            foreach ($result as $v){
                echo "<pre>";
                var_dump( $v);
                echo "</pre>";
            }
    
        }
    
        #生成器
        function readCsv( $file ){
    
            $fp = fopen($file,'rb');
    
            while( !feof($fp) ){
                yield fgetcsv($fp);
            }
    
            fclose($fp);
        }
    

    代码细节可以看我的github片段

  • 相关阅读:
    Navicat 总是断开连接
    MySQL 重连机制
    优化 一
    python之 paramiko模块 连接服务器
    变量值的修改
    Python使用APScheduler实现定时任务
    Linux命令 清空文件
    输入法 | 输入法如何打出直角引号
    Java | Java字节码
    英语 | 图片学习单词
  • 原文地址:https://www.cnblogs.com/followyou/p/9494462.html
Copyright © 2020-2023  润新知