生成器來解決大文件讀取,大數據下載
阿新 • • 發佈:2018-08-17
als fclose 非叠代 tro class php fgetc 內存溢出 con
目錄
- 場景
- 下載文件
- 讀取大文件
場景
電商平臺想要導出一年的報表數據,數據可能有百萬,平常的做法是查出所有數據放到數組或對象中,再進行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片段
生成器來解決大文件讀取,大數據下載