下載本文檔
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
PHP百萬(wàn)級(jí)數(shù)據(jù)導(dǎo)出方案(多csv文件壓縮)實(shí)例講解概述:最近公司項(xiàng)目要求把數(shù)據(jù)除了頁(yè)面輸出也希望有導(dǎo)出功能,雖然之前也做過(guò)幾個(gè)導(dǎo)出功能,但這次數(shù)據(jù)量相對(duì)比較大,差不多一天數(shù)據(jù)就20W條,要求導(dǎo)7天或者30天,那么數(shù)據(jù)量就輕松破百萬(wàn)了甚至破千萬(wàn),因此開發(fā)的過(guò)程中發(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è)置問(wèn)題,但如果你數(shù)據(jù)達(dá)到了百萬(wàn)級(jí)導(dǎo)出,往往30秒是不夠的,因此你需要在你的腳本中添加settimelimit(0),讓該腳本沒(méi)有執(zhí)行時(shí)間現(xiàn)在memorylimit-PHP的內(nèi)存限定:此配置?般php默認(rèn)是128M,如果之前做過(guò)小數(shù)據(jù)的朋友可能也會(huì)動(dòng)過(guò)這個(gè)配置就能解決許多問(wèn)題,或許有人想,你大數(shù)據(jù)也把這個(gè)調(diào)大不就行了嗎?那么真的是t。。youngtoonative了,你本地能設(shè)置1G或者無(wú)限制或許真的沒(méi)問(wèn)題,但是正式場(chǎng),你這么搞遲早會(huì)出事的,一個(gè)PHP程序占那么大的內(nèi)存的空間,如果你叫你公司運(yùn)維幫忙調(diào)一下配置,估計(jì)運(yùn)維一定很不情愿,服務(wù)器硬件這么搞也是太奢侈了。所以說(shuō),我們要盡量避免調(diào)大該設(shè)置。2、excel坑:既然是導(dǎo)出數(shù)據(jù),大伙們當(dāng)然馬上想到了excel格式了,多方便查看數(shù)據(jù)呀,然而萬(wàn)萬(wàn)沒(méi)想到excel也是有脾氣的呀!表數(shù)據(jù)限制:Excel2003及以下的版本。一張表最大支持65536行數(shù)據(jù),256列。Excel2007-2010版本。一張表最大支持1048576行,16384列。
也就是說(shuō)你想幾百萬(wàn)條輕輕松松一次性導(dǎo)入一張EXCEL表是不行的,你起碼需要進(jìn)行數(shù)據(jù)分割,保證數(shù)據(jù)不能超過(guò)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ù)來(lái)導(dǎo)入多個(gè)數(shù)據(jù)表,但是最后PHPexcel內(nèi)部還是一次性把所有表數(shù)據(jù)放進(jìn)一個(gè)變量中來(lái)創(chuàng)建文件……額,這幾百萬(wàn)數(shù)據(jù)一個(gè)變量存儲(chǔ),你想內(nèi)存不溢出,還真有點(diǎn)困難。(后來(lái)看了一些文章發(fā)現(xiàn)PHPExcel也有解決方案,PHPExcel_Settings::setCacheStorageMethod方法更改緩沖方式來(lái)減小內(nèi)存的使用)3、csv坑:EXCEL這么麻煩,我不用還不行嗎?我用csv文件儲(chǔ)存,既不限制數(shù)量,還能直接用EXCEL來(lái)查看,又能以后把文件導(dǎo)入數(shù)據(jù)庫(kù),一舉幾得豈不是美哉?咦,少俠好想法!但是CSV也有坑哦!輸出buffer過(guò)多:當(dāng)你用PHP原生函數(shù)putcsvO其實(shí)就使用到了輸出緩存buffer,如果你把幾百萬(wàn)的數(shù)據(jù)一直用這個(gè)函數(shù)輸出,會(huì)導(dǎo)致輸出緩存太大而報(bào)錯(cuò)的,因此我們每隔一定量的時(shí)候,必須進(jìn)行將輸出緩存中的內(nèi)容取出來(lái),設(shè)置為等待輸出狀態(tài)。具體操作是:ob_flush();flush();具體說(shuō)明介紹:PHPflush。與ob_flush0的區(qū)別詳解EXCEL查看CSV文件數(shù)量限制:大多數(shù)人看csv文件都是直接用EXCEL打開的。額,這不就是回到EXCEL坑中了嗎?EXCEL有數(shù)據(jù)顯示限制呀,你幾百萬(wàn)數(shù)據(jù)只給你看I04W而已。什么?你不管?那是他們打開方式不對(duì)而已?不好不好,我們解決也不難呀,我們也把數(shù)據(jù)分割一下就好了,再分開csv文件保存,反正你不分割數(shù)據(jù)變量也會(huì)內(nèi)存溢出。4、總結(jié)做法分析完上面那些坑,那么我們的解決方案來(lái)了,假設(shè)數(shù)據(jù)量是幾百萬(wàn)。
1、那么我們要從數(shù)據(jù)庫(kù)中讀取要進(jìn)行數(shù)據(jù)量分批讀取,以防變量?jī)?nèi)存溢出,2、我們選擇數(shù)據(jù)保存文件格式是csv文件,以方便導(dǎo)出之后的閱讀、導(dǎo)入數(shù)據(jù)庫(kù)等操作。3、以防不方便excel讀取csv文件,我們需要104W之前就得把數(shù)據(jù)分割進(jìn)行多個(gè)csv文件保存4、多個(gè)csv文件輸出給用戶下載是不友好的,我們還需要把多個(gè)csv文件進(jìn)行壓縮,最后提供給一個(gè)ZIP格式的壓縮包給用戶下載就好。代碼:〃導(dǎo)出說(shuō)明:因?yàn)镋XCEL單表只能顯示104W數(shù)據(jù),同時(shí)使用PHPEXCEL容易因?yàn)閿?shù)據(jù)量太大而導(dǎo)致占用內(nèi)存過(guò)大,//因此,數(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ù)庫(kù)取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ù)通過(guò)fputcsv寫到文件句柄fputcsv($fp,$head);
$dataArr=$data->offset($i*$sqlLimit)->limit($sqlLimit)->get()->toArray();foreach($dataArras$a){$cnt++;if($limit==$cnt){〃刷新一下輸出buffer,防止由于數(shù)據(jù)過(guò)多造成問(wèn)題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. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 大學(xué)生就業(yè)意向協(xié)議書范本
- 兼職協(xié)議參考樣本
- 家具銷售代理協(xié)議
- 店面租賃合同談判要點(diǎn)
- 城市慢行系統(tǒng)景觀設(shè)計(jì)合同
- 應(yīng)收賬款質(zhì)押借款合同的格式參考
- 結(jié)構(gòu)化面試評(píng)分標(biāo)準(zhǔn)細(xì)則
- 鏈?zhǔn)絺鲃?dòng)裝置課程設(shè)計(jì)
- 快遞員勞動(dòng)合同樣本
- 軟件課程設(shè)計(jì)送水系統(tǒng)
- 門診病人回訪登記表
- 安全事故急救知識(shí)培訓(xùn)
- 醫(yī)學(xué)遺傳學(xué)課件:亨廷頓舞蹈癥
- 最新-頸椎骨折的護(hù)理查房課件
- 鮑曼不動(dòng)桿菌的治療課件
- 催眠術(shù)-第二講課件
- 國(guó)家科技進(jìn)步獎(jiǎng)答辯通用PPT模板(推薦)
- 《幼兒園家園共育研究開題報(bào)告(含提綱)》
- 消化科突發(fā)事件應(yīng)急預(yù)案及處置程序
- 《中醫(yī)推拿按摩》課件
- 國(guó)家5A景區(qū)創(chuàng)建簡(jiǎn)介課件
評(píng)論
0/150
提交評(píng)論