



下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
PHP百萬級(jí)數(shù)據(jù)導(dǎo)出方案(多csv文件壓縮)實(shí)例講解概述:最近公司項(xiàng)目要求把數(shù)據(jù)除了頁面輸出也希望有導(dǎo)出功能,雖然之前也做過幾個(gè)導(dǎo)出功能,但這次數(shù)據(jù)量相對(duì)比較大,差不多一天數(shù)據(jù)就20W條,要求導(dǎo)7天或者30天,那么數(shù)據(jù)量就輕松破百萬了甚至破千萬,因此開發(fā)的過程中發(fā)現(xiàn)了一些大數(shù)據(jù)導(dǎo)出的坑,在此跟大家分享一下,互相學(xué)習(xí)。準(zhǔn)備:1、PHP設(shè)置坑:set_time」imit-設(shè)置腳本最大執(zhí)行時(shí)間:此配置?般PHP默認(rèn)是30秒,如果你是數(shù)據(jù)小的,可能就不會(huì)發(fā)現(xiàn)有該設(shè)置問題,但如果你數(shù)據(jù)達(dá)到了百萬級(jí)導(dǎo)出,往往30秒是不夠的,因此你需要在你的腳本中添加settimelimit(0),讓該腳本沒有執(zhí)行時(shí)間現(xiàn)在memorylimit-PHP的內(nèi)存限定:此配置?般php默認(rèn)是128M,如果之前做過小數(shù)據(jù)的朋友可能也會(huì)動(dòng)過這個(gè)配置就能解決許多問題,或許有人想,你大數(shù)據(jù)也把這個(gè)調(diào)大不就行了嗎?那么真的是t。。youngtoonative了,你本地能設(shè)置1G或者無限制或許真的沒問題,但是正式場(chǎng),你這么搞遲早會(huì)出事的,一個(gè)PHP程序占那么大的內(nèi)存的空間,如果你叫你公司運(yùn)維幫忙調(diào)一下配置,估計(jì)運(yùn)維一定很不情愿,服務(wù)器硬件這么搞也是太奢侈了。所以說,我們要盡量避免調(diào)大該設(shè)置。2、excel坑:既然是導(dǎo)出數(shù)據(jù),大伙們當(dāng)然馬上想到了excel格式了,多方便查看數(shù)據(jù)呀,然而萬萬沒想到excel也是有脾氣的呀!表數(shù)據(jù)限制:Excel2003及以下的版本。一張表最大支持65536行數(shù)據(jù),256列。Excel2007-2010版本。一張表最大支持1048576行,16384列。
也就是說你想幾百萬條輕輕松松一次性導(dǎo)入一張EXCEL表是不行的,你起碼需要進(jìn)行數(shù)據(jù)分割,保證數(shù)據(jù)不能超過104W一張表。PHPexcel內(nèi)存溢出:既然數(shù)據(jù)限制在104W,那么數(shù)據(jù)分割就數(shù)據(jù)分割唄,于是你嘗試50W-次導(dǎo)入表,然而PHPexcel內(nèi)部有函數(shù)報(bào)內(nèi)存溢出錯(cuò)誤,然后你就不斷的調(diào)小數(shù)據(jù)量,直到5W一次導(dǎo)入你都會(huì)發(fā)現(xiàn)有內(nèi)存溢出錯(cuò)誤。這是為什么呢,雖然你分割數(shù)據(jù)來導(dǎo)入多個(gè)數(shù)據(jù)表,但是最后PHPexcel內(nèi)部還是一次性把所有表數(shù)據(jù)放進(jìn)一個(gè)變量中來創(chuàng)建文件……額,這幾百萬數(shù)據(jù)一個(gè)變量存儲(chǔ),你想內(nèi)存不溢出,還真有點(diǎn)困難。(后來看了一些文章發(fā)現(xiàn)PHPExcel也有解決方案,PHPExcel_Settings::setCacheStorageMethod方法更改緩沖方式來減小內(nèi)存的使用)3、csv坑:EXCEL這么麻煩,我不用還不行嗎?我用csv文件儲(chǔ)存,既不限制數(shù)量,還能直接用EXCEL來查看,又能以后把文件導(dǎo)入數(shù)據(jù)庫,一舉幾得豈不是美哉?咦,少俠好想法!但是CSV也有坑哦!輸出buffer過多:當(dāng)你用PHP原生函數(shù)putcsvO其實(shí)就使用到了輸出緩存buffer,如果你把幾百萬的數(shù)據(jù)一直用這個(gè)函數(shù)輸出,會(huì)導(dǎo)致輸出緩存太大而報(bào)錯(cuò)的,因此我們每隔一定量的時(shí)候,必須進(jìn)行將輸出緩存中的內(nèi)容取出來,設(shè)置為等待輸出狀態(tài)。具體操作是:ob_flush();flush();具體說明介紹:PHPflush。與ob_flush0的區(qū)別詳解EXCEL查看CSV文件數(shù)量限制:大多數(shù)人看csv文件都是直接用EXCEL打開的。額,這不就是回到EXCEL坑中了嗎?EXCEL有數(shù)據(jù)顯示限制呀,你幾百萬數(shù)據(jù)只給你看I04W而已。什么?你不管?那是他們打開方式不對(duì)而已?不好不好,我們解決也不難呀,我們也把數(shù)據(jù)分割一下就好了,再分開csv文件保存,反正你不分割數(shù)據(jù)變量也會(huì)內(nèi)存溢出。4、總結(jié)做法分析完上面那些坑,那么我們的解決方案來了,假設(shè)數(shù)據(jù)量是幾百萬。
1、那么我們要從數(shù)據(jù)庫中讀取要進(jìn)行數(shù)據(jù)量分批讀取,以防變量內(nèi)存溢出,2、我們選擇數(shù)據(jù)保存文件格式是csv文件,以方便導(dǎo)出之后的閱讀、導(dǎo)入數(shù)據(jù)庫等操作。3、以防不方便excel讀取csv文件,我們需要104W之前就得把數(shù)據(jù)分割進(jìn)行多個(gè)csv文件保存4、多個(gè)csv文件輸出給用戶下載是不友好的,我們還需要把多個(gè)csv文件進(jìn)行壓縮,最后提供給一個(gè)ZIP格式的壓縮包給用戶下載就好。代碼:〃導(dǎo)出說明:因?yàn)镋XCEL單表只能顯示104W數(shù)據(jù),同時(shí)使用PHPEXCEL容易因?yàn)閿?shù)據(jù)量太大而導(dǎo)致占用內(nèi)存過大,//因此,數(shù)據(jù)的輸出用csv文件的格式輸出,但是csv文件用EXCEL軟件讀取同樣會(huì)存在只能顯示104W的情況,所以將數(shù)據(jù)分割保存在多個(gè)CSV文件中,并且最后壓縮成zip文件提供下載8910111213functionputCsv(array$head,$data,$mark=8910111213set_time_limit(0);$sqlCount=$data->count();//輸出Excel文件頭,可把user.csv換成你要的文件名header('Content-Type:application/vnd.ms-excel;charset=utf-8'header('Content-Disposition:attachment;filename="'.14$fileName?15161718151617181920212223242526272829$sqlLimit=100000;〃每次只從數(shù)據(jù)庫取100000條以防變量緩存太大//每隔行,刷新一下輸出buffer,不要太大,也不要太小$limit=100000;//buffer計(jì)數(shù)器$cnt=0;$fileNameArr=array();//逐行取出數(shù)據(jù),不浪費(fèi)內(nèi)存for($i=0;$i<ceil($sqlCount/$sqlLimit);$i++){$fp=fopen($mark. .$i,*.csv','w');〃生成臨時(shí)文件//chmod('attack_ip_info_'.$i.'.csv',777);〃修改可執(zhí)行權(quán)限//$i,*.csv';$i,*.csv';//將數(shù)據(jù)通過fputcsv寫到文件句柄fputcsv($fp,$head);
$dataArr=$data->offset($i*$sqlLimit)->limit($sqlLimit)->get()->toArray();foreach($dataArras$a){$cnt++;if($limit==$cnt){〃刷新一下輸出buffer,防止由于數(shù)據(jù)過多造成問題ob__flush();flush();$cnt=0;)fputcsv($fp,$a);)fclose($fp);〃每生成一個(gè)文件關(guān)閉)//進(jìn)行多個(gè)文件壓縮$zip=newZipArchive();$filename=$mark.".zip";$zip->open($filenameJZipArchive::CREATE);〃打開壓縮包foreach($fileNameArras$file){$zip->addFile($file>basename($file)); 〃向壓縮包中添加文件)$zip->close();〃關(guān)閉壓縮包foreach($fileNameArras$file){unlink($file);〃刪除csv臨時(shí)文件)55 〃輸出壓縮文件提供下載header("Cache-Control:max-age=0");header("Content-Description:FileTransfer");header('Content-disposition:attachment;filename='.basename($filename));//文件名header("Content-Type:application/zip");//zip格式的header("Content-Transfer-Encoding:binary");//header('Content-Length:'.filesize($filename));//@r
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 道路改造與混凝土管鋪設(shè)施工方案設(shè)計(jì)及舊路面拆除策略探討
- 醫(yī)用織物清洗管理辦法
- 加強(qiáng)資金安全管理措施
- 安全工作周例會(huì)
- 數(shù)字時(shí)代背景下人類存在性危機(jī)的哲學(xué)思考與應(yīng)對(duì)策略
- 車間安全培訓(xùn)主要內(nèi)容
- 《昆蟲記》主題分析及高考備考要點(diǎn)研究
- 安全管理部述職報(bào)告
- 快遞安全生產(chǎn)責(zé)任制度范本
- 安全生產(chǎn)工作責(zé)任清單
- 新聞采編培訓(xùn)課件
- 來料檢驗(yàn)規(guī)范
- 電鍍產(chǎn)品檢驗(yàn)記錄
- 2023-2024學(xué)年遼寧省大連市小學(xué)語文五年級(jí)期末評(píng)估試卷附參考答案和詳細(xì)解析
- 2023年小學(xué)數(shù)學(xué)必背定義和公式
- 2023年四川省宜賓市全科醫(yī)學(xué)專業(yè)實(shí)踐技能測(cè)試卷(含答案)
- 興平市生活垃圾焚燒發(fā)電項(xiàng)目環(huán)評(píng)報(bào)告
- 主令電器(課用)課件
- 湘少版英語六年級(jí)下冊(cè)全冊(cè)教案
- 湖南省長郡中學(xué)“澄池”杯數(shù)學(xué)競賽初賽試題(掃描版含答案)
- 消防系統(tǒng)施工總進(jìn)度計(jì)劃
評(píng)論
0/150
提交評(píng)論