PHP處理DBase數(shù)據(jù)庫(kù)


我是Lem0擎淤,自學(xué)倡導(dǎo)者奢啥,執(zhí)迷于“不務(wù)正業(yè)”,被批評(píng)“旁門左道”嘴拢。我注冊(cè)并使用簡(jiǎn)書桩盲,希望能夠記錄一些我記不住的事情,或者與大家一起共享知識(shí)席吴,共同學(xué)習(xí)赌结。

從導(dǎo)師那里接到這個(gè)項(xiàng)目的時(shí)候,我還認(rèn)為DBase數(shù)據(jù)庫(kù)已經(jīng)從這個(gè)世界上消失了孝冒,沒有一家公司和企業(yè)依然在使用DBF文件存儲(chǔ)數(shù)據(jù)柬姚。然而我想錯(cuò)了,我國(guó)教育部門依然在使用這種格式的文件庄涡,無論是我手中合法獲取的數(shù)據(jù)量承,還是其他部門人員透露的消息,DBF數(shù)據(jù)文件確實(shí)從學(xué)生高考入學(xué)到畢業(yè)時(shí)填寫去向表都一直存在著穴店,并且在短時(shí)間內(nèi)撕捍,教育系統(tǒng)中不會(huì)有其他來代替DBase數(shù)據(jù)庫(kù)。

基于這種情況泣洞,這個(gè)數(shù)據(jù)可視化項(xiàng)目可以概括為提取我手中DBF文件里的100萬條數(shù)據(jù)并加以處理忧风,繪制統(tǒng)計(jì)圖表。

PHP的DBase擴(kuò)展

我是用的后端語言是PHP斜棚,開發(fā)環(huán)境是Windows8+wamp阀蒂。為了讓PHP能夠處理DBF文件,我需要下載安裝一個(gè)名為php_dbase.dll的擴(kuò)展庫(kù)弟蚀。

我搜遍全網(wǎng),發(fā)現(xiàn)PHP5.3時(shí)期已經(jīng)完全棄用dbase擴(kuò)展和相關(guān)函數(shù)的使用酗失。我的wamp搭載的是PHP5.5义钉,自然不能使用php_dbase.dll了。

后來我在PHP官網(wǎng)上搜索规肴,得到PHP7.0支持dbase數(shù)據(jù)庫(kù)擴(kuò)展的消息捶闸。我快速下載了最新版本的wamp夜畴,支持PHP5和PHP7的相互轉(zhuǎn)換。之后我使用PHP7.0.10成功地載入了php_dbase.dll删壮。

處理DBF文件

我在PHP手冊(cè)中查得操作DBF文件的多個(gè)函數(shù)贪绘,功能簡(jiǎn)單但足夠我使用。

//打開數(shù)據(jù)庫(kù)央碟,其中第二參數(shù)為打開方式:
0-只讀税灌;1-只寫;2-可讀寫
dbase_open($filename, $mode)

//關(guān)閉數(shù)據(jù)庫(kù)
dbase_close($identifier)

//讀取一條記錄亿虽,返回一個(gè)關(guān)系型數(shù)組
dbase_get_record_with_names($identifier, $index)

//獲取數(shù)據(jù)庫(kù)中數(shù)據(jù)總條數(shù)
dbase_numrecords($identifier)

首先我使用一個(gè)循環(huán)菱涤,讀取每一條數(shù)據(jù)并進(jìn)行處理:

for ($i = 0; $i < $dbase_numrecord($db); $i++) {
  $row = dbase_get_record_with_names($db, $i);
  //...其他處理
}

寫成整個(gè)程序之后我發(fā)現(xiàn),由于PHP本身的效率問題洛勉,加之?dāng)?shù)據(jù)量龐大(100萬條數(shù)據(jù))粘秆,我的瀏覽器在運(yùn)行PHP程序時(shí)總會(huì)卡死,造成約5~10分鐘的無響應(yīng)狀態(tài)收毫。我判斷一次讀取和處理的數(shù)據(jù)不能大于5000條攻走,所以我嵌套了另一個(gè)外部循環(huán),保證每次循環(huán)處理5000個(gè)數(shù)據(jù)此再,5000條數(shù)據(jù)都處理完陋气,再讀入下5000條。之后根據(jù)運(yùn)行結(jié)果來看引润,我已經(jīng)能夠做到秒級(jí)輸出處理結(jié)果了巩趁。

繪圖插件

我一開始打算使用PHP的類庫(kù):jpgraph來繪制統(tǒng)計(jì)圖表。但后來我被百度前端推出的圖標(biāo)插件echarts的效果吸引了淳附,因而決定使用echarts配合jQuery出圖议慰。

依舊是效率

我發(fā)現(xiàn)每次登錄系統(tǒng)都采取PHP運(yùn)算,讀入DBF后出圖是一個(gè)愚蠢的決定奴曙,因?yàn)檫@將導(dǎo)致打開數(shù)據(jù)庫(kù)别凹,可能處理大量不需要用戶看到的信息,從而拖慢機(jī)器速度洽糟。

我冥思苦想炉菲,最終發(fā)現(xiàn)了echarts插件支持通過json繪圖。我一下拍案而起坤溃,可以通過PHP處理數(shù)據(jù)庫(kù)一次拍霜,將獲得的、需要使用的數(shù)據(jù)儲(chǔ)存到j(luò)son中薪介。每次得到用戶的請(qǐng)求祠饺,都從json中加載數(shù)據(jù)。

這就避免了大量不需要的數(shù)據(jù)儲(chǔ)存在服務(wù)器上汁政,浪費(fèi)空間道偷,從而也避免了可能的安全問題缀旁。同時(shí),使用json相比于從DBF直接讀入數(shù)據(jù)快了很多倍勺鸦,一個(gè)json文件只有100kb而已(之前的dbf文件有足足300M)并巍。

之后我依舊使用上面每次讀取5000條數(shù)據(jù)的循環(huán),將讀取的數(shù)據(jù)以json格式輸出并儲(chǔ)存换途。

//for循環(huán)體
$row = dbase_get_record_with_names($db, $i);

switch ($row['JYQXDM']) {
  //處理語句省略懊渡,處理結(jié)果是數(shù)組形式,賦給變量$res
}

json_encode($res);
echo $res;

在程序確認(rèn)無誤后怀跛,發(fā)現(xiàn)輸出無效距贷。頁面沒有顯示任何內(nèi)容。

中文編碼

json_encode函數(shù)要求json數(shù)據(jù)必須是utf-8編碼吻谋。但即使用UTF8編碼的字符忠蝗,使用json_encode也沒有輸出。后來我又查了一個(gè)小時(shí)漓拾,才找到了解決辦法阁最。

我在使用json_encode之前把字符用函數(shù)urlencode()處理一下,然后再json_encode骇两,輸出結(jié)果的時(shí)候在用函數(shù)urldecode()轉(zhuǎn)回來速种。測(cè)試代碼具體如下:

$testJSON=array('name'=>'中文字符串','value'=>'test');  

foreach ( $testJSON as $key => $value ) {  
$testJSON[$key] = urlencode ( $value );  
    }  
echo urldecode ( json_encode ( $testJSON ) );

至此,PHP終于輸出了中文json格式低千。


關(guān)注我的諸位配阵,感謝你們的支持。

由于工作原因示血,最近沒有時(shí)間更新游戲開發(fā)教程和其他文章棋傍。我正著手于一個(gè)數(shù)據(jù)可視化系統(tǒng)的項(xiàng)目,可能在最近5天內(nèi)沒有時(shí)間再看簡(jiǎn)書并且回復(fù)大家的私信和評(píng)論难审。您可以繼續(xù)留言給我瘫拣,我會(huì)盡早回來繼續(xù)更新。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末告喊,一起剝皮案震驚了整個(gè)濱河市麸拄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌黔姜,老刑警劉巖拢切,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異地淀,居然都是意外死亡失球,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門帮毁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來实苞,“玉大人,你說我怎么就攤上這事烈疚∏#” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵爷肝,是天一觀的道長(zhǎng)猾浦。 經(jīng)常有香客問我,道長(zhǎng)灯抛,這世上最難降的妖魔是什么金赦? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮对嚼,結(jié)果婚禮上夹抗,老公的妹妹穿的比我還像新娘。我一直安慰自己纵竖,他們只是感情好漠烧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著靡砌,像睡著了一般已脓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上通殃,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天度液,我揣著相機(jī)與錄音,去河邊找鬼画舌。 笑死堕担,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的骗炉。 我是一名探鬼主播照宝,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼句葵!你這毒婦竟也來了厕鹃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤乍丈,失蹤者是張志新(化名)和其女友劉穎剂碴,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體轻专,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡忆矛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片催训。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡洽议,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出漫拭,到底是詐尸還是另有隱情亚兄,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布采驻,位于F島的核電站审胚,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏礼旅。R本人自食惡果不足惜膳叨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望痘系。 院中可真熱鬧菲嘴,春花似錦、人聲如沸碎浇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽召嘶。三九已至鹤耍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間苟穆,已是汗流浹背抄课。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留雳旅,地道東北人跟磨。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像攒盈,于是被迫代替她去往敵國(guó)和親抵拘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容