您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)怎么在PHP中實(shí)現(xiàn)序列化,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
一、PHP 序列化變量的 4 種方法
序列化是將變量轉(zhuǎn)換為可保存或傳輸?shù)淖址倪^程;反序列化就是在適當(dāng)?shù)臅r(shí)候把這個(gè)字符串再轉(zhuǎn)化成原來的變量使用。這兩個(gè)過程結(jié)合起來,可以輕松地存儲(chǔ)和傳輸數(shù)據(jù),使程序更具維護(hù)性。
1. serialize和unserialize函數(shù)
這兩個(gè)是序列化和反序列化PHP中數(shù)據(jù)的常用函數(shù)。
$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut'); //序列化數(shù)組 $s = serialize($a); echo $s; //輸出結(jié)果:a:3:{s:1:"a";s:5:"Apple";s:1:"b";s:6:"banana";s:1:"c";s:7:"Coconut";} echo '<br /><br />'; //反序列化 $o = unserialize($s); print_r($o);
當(dāng)數(shù)組值包含如雙引號(hào)、單引號(hào)或冒號(hào)等字符時(shí),它們被反序列化后,可能會(huì)出現(xiàn)問題。為了克服這個(gè)問題,一個(gè)巧妙的技巧是使用base64_encode和base64_decode。
$obj = array(); //序列化 $s = base64_encode(serialize($obj)); //反序列化 $original = unserialize(base64_decode($s));
但是base64編碼將增加字符串的長(zhǎng)度。為了克服這個(gè)問題,可以和gzcompress一起使用。
//定義一個(gè)用來序列化對(duì)象的函數(shù) function my_serialize( $obj ) { return base64_encode(gzcompress(serialize($obj))); } //反序列化 function my_unserialize($txt) { return unserialize(gzuncompress(base64_decode($txt))); }
2. json_encode 和 json_decode
使用JSON格式序列化和反序列化是一個(gè)不錯(cuò)的選擇:
使用json_encode和json_decode格式輸出要serialize和unserialize格式快得多。
JSON格式是可讀的。
JSON格式比serialize返回?cái)?shù)據(jù)結(jié)果小。
JSON格式是開放的、可移植的。其他語言也可以使用它。
$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut'); //序列化數(shù)組 $s = json_encode($a); echo $s; //輸出結(jié)果:{"a":"Apple","b":"banana","c":"Coconut"} echo '<br /><br />'; //反序列化 $o = json_decode($s);
在上面的例子中,json_encode輸出長(zhǎng)度比上個(gè)例子中serialize輸出長(zhǎng)度顯然要短。
3. var_export 和 eval
var_export 函數(shù)把變量作為一個(gè)字符串輸出;eval把字符串當(dāng)成PHP代碼來執(zhí)行,反序列化得到最初變量的內(nèi)容。
$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut'); //序列化數(shù)組 $s = var_export($a , true); echo $s; //輸出結(jié)果: array ( 'a' => 'Apple', 'b' => 'banana', 'c' => 'Coconut', ) echo '<br /><br />'; //反序列化 eval('$my_var=' . $s . ';'); print_r($my_var);
4. wddx_serialize_value 和 wddx deserialize
wddx_serialize_value函數(shù)可以序列化數(shù)組變量,并以XML字符串形式輸出。
$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut'); //序列化數(shù)組 $s = wddx_serialize_value($a); echo $s; //輸出結(jié)果(查看輸出字符串的源碼):<wddxPacket version='1.0'><header/><data><struct><var name='a'><string>Apple</string></var><var name='b'><string>banana</string></var><var name='c'><string>Coconut</string></var></struct></data></wddxPacket> echo '<br /><br />'; //反序列化 $o = wddx_deserialize($s); print_r($o); //輸出結(jié)果:Array ( [a] => Apple [b] => banana 1 => Coconut )
可以看出,XML標(biāo)簽字符較多,導(dǎo)致這種格式的序列化還是占了很多空間。
結(jié)論
上述所有的函數(shù)在序列化數(shù)組變量時(shí)都能正常執(zhí)行,但運(yùn)用到對(duì)象就不同了。例如json_encode序列化對(duì)象就會(huì)失敗。反序列化對(duì)象時(shí),unserialize和eval將有不同的效果。
英文原文:3 ways to serialize variables in php
二、PHP四種序列化方案橫向?qū)Ρ?/strong>
數(shù)據(jù)的序列化是一個(gè)非常有用的功能,然而目測(cè)很多人跟我一樣,在剛接觸這玩意的時(shí)候壓根就不理解這貨色到底是干啥用的,反正老師說了,實(shí)在理解不了就先背過再說。
其實(shí)將數(shù)據(jù)序列化的作用無外乎有兩個(gè):
方便傳輸
方便存儲(chǔ)
方便存儲(chǔ)如何理解呢?比如我們有個(gè)PHP對(duì)象或者一個(gè)PHP數(shù)組需要存儲(chǔ)到數(shù)據(jù)庫甚至文件中,這顯然是不可能的,這個(gè)時(shí)候必須要將PHP對(duì)象或者PHP數(shù)組序列化后再執(zhí)行存儲(chǔ)操作。不過這將PHP數(shù)組序列化后存起來還能理解,這對(duì)象也能存儲(chǔ)?。窟@操作是否過于風(fēng)騷?少年,這一點(diǎn)兒都不風(fēng)騷。有些時(shí)候?qū)?duì)象直接存儲(chǔ)起來,用的時(shí)候只需要簡(jiǎn)單的反序列化后就可以投產(chǎn)使用了,避免了new一次帶來的性能耗費(fèi)。
方便傳輸如何理解呢?其實(shí)序列化在傳輸中應(yīng)用的相對(duì)更多更常見些許。最簡(jiǎn)單的一個(gè)例子,一個(gè)碼前端的碼了一個(gè)ajax找你給TA提供一個(gè)API,那么這個(gè)時(shí)候你倆得商量返回什么數(shù)據(jù),比如json或者xml,甚至你倆自己作死約定私有數(shù)據(jù)格式。比如在一個(gè)比較典型的服務(wù)架構(gòu)中,網(wǎng)關(guān)服務(wù)器和內(nèi)部RPC服務(wù)器之間通過msgpack傳遞數(shù)據(jù)。這都是典型的序列化為了傳輸?shù)牡湫蛻?yīng)用案例。
這里序列化的概念可能更為廣泛和籠統(tǒng)一些,包括傳統(tǒng)的serialize、json、msgpack、protobuf等。( 如果你覺得序列化這個(gè)稱呼不太嚴(yán)謹(jǐn)?shù)脑挘梢杂胑ncode來代替;反序列化則用decode來代替。反正我就用統(tǒng)統(tǒng)用序列化和反序列化來稱呼了,如果你覺得實(shí)在不舒服,可以順著網(wǎng)線來砍我?。?/p>
實(shí)際上,從更高的層面看,數(shù)據(jù)的序列化可以分為兩種:
文本序列化,常見如json、serialize、xml等
二進(jìn)制序列化,常見如msgpack、protobuf、thrift等
一般說來,考驗(yàn)序列化技術(shù)的性能指標(biāo)一共有兩個(gè),一個(gè)是序列化的速度,一個(gè)是序列化后數(shù)據(jù)的大小,自然是序列化速度越快、序列化后的數(shù)據(jù)越小為佳。就目前來看,protobuf、msgpack等二進(jìn)制序列化無論是速度上還是數(shù)據(jù)大小上,都要比文本序列化更好。不過話說回來,文本序列化有更好的可讀性,一眼就能瞪出來數(shù)據(jù)內(nèi)容大概是啥玩意。
今天帶到這里的這里的有四個(gè)具體的方案,這四種方案都是簡(jiǎn)單粗暴、開箱即用類型的,我們分別測(cè)試感受下,看哪個(gè)更適合我們。
參會(huì)的四個(gè)哥們:PHP內(nèi)置的serialize、PHP內(nèi)置的JSON解析器、PHP擴(kuò)展JSOND、PHP擴(kuò)展msgpack。其中前三個(gè)都是文本類型的,msgpack則是二進(jìn)制類型的。
JSOND作為PHP內(nèi)置的JSON解析器的高級(jí)版本,坊間一直傳聞速度上要比內(nèi)置的更牛X一些,作為擴(kuò)展,這貨需要額外安裝,附送地址:https://pecl.php.net/get/jsond-1.4.0.tgz。
msgpack是一個(gè)鳥哥等人搞的一套二進(jìn)制序列化工具,slogan就是“It's like JSON.but fast and small.”,附送地址:https://pecl.php.net/get/msgpack-2.0.2.tgz
1、serialize用法
serialize(),序列化方法。
unserialize(),反序列化方法。
2、json用法
json_encode(),沒啥好說的吧?
json_decode(),沒啥好說的吧?
3、jsond用法
jsond_encode(),和json_encode()一樣,后面多個(gè)字母d而已。
jsond_decode(),和json_decode()一樣,后面多個(gè)字母d而已。
4、msgpack用法
msgpack_pack(),序列化方法。
msgpack_unpack(),反序列化方法。
測(cè)試代碼如下:
<?php // 故意搞了一個(gè)還算大的php數(shù)組,更容易看出差距來 $arr = array( array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), 'relation' => array( array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), ), ) ); // 每種序列化方案都執(zhí)行100000次 $counter = 100000; // json序列化方案,執(zhí)行100000次 echo PHP_EOL.PHP_EOL; $start = microtime( true ); for( $i = 1; $i <= $counter; $i++ ){ $json = json_encode( $arr ); } $size = strlen( $json ); $end = microtime( true ); $cost_time = $end - $start; echo "json_encode : 耗費(fèi)時(shí)間為{$cost_time} , 數(shù)據(jù)體積為{$size}".PHP_EOL; // jsond序列化方案,執(zhí)行100000次 $start = microtime( true ); for( $i = 1; $i <= $counter; $i++ ){ $jsond = jsond_encode( $arr ); } $size = strlen( $jsond ); $end = microtime( true ); $cost_time = $end - $start; echo "jsond_encode : 耗費(fèi)時(shí)間為{$cost_time} , 數(shù)據(jù)體積為{$size}".PHP_EOL; // serialize序列化方案,執(zhí)行100000次 $start = microtime( true ); for( $i = 1; $i <= $counter; $i++ ){ $serialize = serialize( $arr ); } $size = strlen( $serialize ); $end = microtime( true ); $cost_time = $end - $start; echo "serialize : 耗費(fèi)時(shí)間為{$cost_time} , 數(shù)據(jù)體積為{$size}".PHP_EOL; // msgpack序列化方案,執(zhí)行100000次 $start = microtime( true ); for( $i = 1; $i <= $counter; $i++ ){ $msgpack = msgpack_pack( $arr ); } $size = strlen( $msgpack ); $end = microtime( true ); $cost_time = $end - $start; echo "msgpack耗費(fèi)時(shí)間為 : {$cost_time} , 數(shù)據(jù)體積為{$size}".PHP_EOL; echo PHP_EOL.PHP_EOL;
將文件保存為test.php,然后php test.php執(zhí)行,結(jié)果如下圖所示:
php的框架:1、Laravel,Laravel是一款免費(fèi)并且開源的PHP應(yīng)用框架。2、Phalcon,Phalcon是運(yùn)行速度最快的一個(gè)PHP框架。3、Symfony,Symfony是一款為Web項(xiàng)目準(zhǔn)備的PHP框架。4、Yii,Yii是一款快速、安全和專業(yè)的PHP框架。5、CodeIgniter,CodeIgniter是一款非常敏捷的開源PHP框架。6、CakePHP,CakePHP是一款老牌的PHP框架。7.Kohana,Kohana是一款敏捷但是功能強(qiáng)大的PHP框架。
看完上述內(nèi)容,你們對(duì)怎么在PHP中實(shí)現(xiàn)序列化有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。