PHP里面,有時(shí)候出于實(shí)際需求考慮,需要將某些信息以數(shù)組的方式進(jìn)行存儲,甚至有時(shí)候介于數(shù)組、字符串兩者之間,很難確定是數(shù)組還是字符串,如果最終還需要將這些信息存儲到文件系統(tǒng)中,而且要保證正確無誤的存儲、讀取。能達(dá)到這種效果的有兩組函數(shù),分別是serialize/unserialize和json_encode/json_decode,其中,serialize是將數(shù)組序列化,變成字符串格式,而unserialize正好相反,是將序列化的字符串進(jìn)行反序列化,變成數(shù)組;而json_encode是將變量轉(zhuǎn)換成JSON格式的數(shù)據(jù),而json_decode則是將JSON格式的數(shù)據(jù)轉(zhuǎn)換為對象(數(shù)組、JSON等)。 以下就以上兩組函數(shù)的優(yōu)缺點(diǎn)簡單作個(gè)對比。
前面已經(jīng)說明了情況,不僅要對變量進(jìn)行轉(zhuǎn)義,還要將轉(zhuǎn)義后的內(nèi)容進(jìn)行存儲、讀取,經(jīng)過本人測試發(fā)現(xiàn),在對變量進(jìn)行轉(zhuǎn)義方面serialize/unserialize相比之下要比json_encode/json_decode高效一些,不過,也沒有高得離譜,那么,對于大數(shù)據(jù)方面,二者就有比較大的區(qū)別了。
舉個(gè)例子,通過下面這段代碼,產(chǎn)生一個(gè)包含20萬個(gè)(數(shù)組)元素的數(shù)組,
$module = [];
for($i=0;$i<200000;$i++){
$module[$i] = ['SN'=>$S->doSN(),'str'=>$S->randChar(30)];
}
注:doSN()的作用是產(chǎn)生一個(gè)10位的訂單序列號,randChar(30)是產(chǎn)生一個(gè)30位的隨機(jī)字符串,這兩個(gè)函數(shù)不是本次的重點(diǎn),不作詳解。
通過前面的代碼對$module數(shù)組進(jìn)行賦值,接下來就是對數(shù)組進(jìn)行轉(zhuǎn)義了,實(shí)際操作發(fā)現(xiàn),serialize($module)時(shí)會報(bào)錯(cuò),“Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 14684160 bytes) in ”,如下圖:
大概的意思是內(nèi)存超過了系統(tǒng)允許的14684160B,當(dāng)然也可以修改PHP.INI來加大。而json_encode($module)就不存在這個(gè)問題,雖然說筆者沒有繼續(xù)測試下去看看json_encode會不會也出現(xiàn)內(nèi)存溢出的情況,但是,就目前的情況來說,json_encode似乎要更強(qiáng)大一點(diǎn)。
好了,接著測試另一種情況,“容錯(cuò)”,這里的容錯(cuò)指的是當(dāng)無法判斷需要轉(zhuǎn)義/反轉(zhuǎn)義的變量是數(shù)組還是字符串的情況,如下:
$str = 'PHP'; //簡單的定義一個(gè)字符串變量,
serialize($str)得到的結(jié)果是s:3:"PHP";
json_encode($str)得到的結(jié)果是"PHP";
都沒有報(bào)錯(cuò),同樣的,我們看下反轉(zhuǎn)義的。
unserialize($str)出錯(cuò)了,Notice: unserialize(): Error at offset 0 of 3 bytes in
json_decode($str)沒有報(bào)錯(cuò),返回值是NULL,這個(gè)好理解,畢竟前面的$str中的內(nèi)容不是一個(gè)有效的JSON格式數(shù)據(jù)。
到這里,大概的總結(jié)以下幾點(diǎn):
1、大數(shù)組情況下,JSON組函數(shù)要更耐用;
2、對未知類型的變量進(jìn)行反轉(zhuǎn)義時(shí),JSON組函數(shù)容錯(cuò)性要更理想;
3、相比而言,JSON組函數(shù)轉(zhuǎn)義后的字符串要更短一些,作為文件存儲,可以節(jié)約一定的存儲空間。
順便,對serialize和json_encode的效率進(jìn)行一個(gè)簡單的對比,
$stime = time();
for($i=0;$i<200000;$i++){
serialize(['SN'=>$S->doSN(),'str'=>$S->randChar(30)]);
}
echo '<br><br>進(jìn)行20萬次serialize運(yùn)算花費(fèi)' . (time()-$stime) . '秒';
$stime = time();
for($i=0;$i<200000;$i++){
json_encode(['SN'=>$S->doSN(),'str'=>$S->randChar(30)]);
}
echo '<br><br>進(jìn)行20萬次json_encode運(yùn)算花費(fèi)' . (time()-$stime) . '秒';
通過上面的對比發(fā)現(xiàn),20萬次同樣的操作,serialize比json_encode快1秒,這樣算下來,單次執(zhí)行而言二者基本上是不相上下了。