主頁(yè) > 知識(shí)庫(kù) > PHP序列化的四種實(shí)現(xiàn)方法與橫向?qū)Ρ?/div>

PHP序列化的四種實(shí)現(xiàn)方法與橫向?qū)Ρ?/h1>

熱門標(biāo)簽:智能電銷語音機(jī)器人資訊 400 電話 辦理 兼職做地圖標(biāo)注好賺錢嗎 打開百度地圖標(biāo)注 亳州企業(yè)外呼系統(tǒng) 海南外呼系統(tǒng)方案 山東電銷卡外呼系統(tǒng)原理是什么 地圖標(biāo)注怎么做商戶驗(yàn)證 蘇州外呼系統(tǒng)有效果嗎

一、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ù)庫(kù)甚至文件中,這顯然是不可能的,這個(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ù)脑?,可以用encode來代替;反序列化則用decode來代替。反正我就用統(tǒng)統(tǒng)用序列化和反序列化來稱呼了,如果你覺得實(shí)在不舒服,可以順著網(wǎng)線來砍我?。?。

實(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é)果如下圖所示:

總結(jié)一下:

  1. jsond確實(shí)是要比json快一些的
  2. 總有刁民張嘴就來json要比serialize()快
  3. serialize()數(shù)據(jù)體積確實(shí)大(因?yàn)檫€保留了數(shù)據(jù)類型說明)
  4. msgpack最佳???不知道昂,你們自己感受

您可能感興趣的文章:
  • PHP 序列化和反序列化函數(shù)實(shí)例詳解
  • 解析PHP多種序列化與反序列化的方法
  • php json與xml序列化/反序列化
  • php 中序列化和json使用介紹
  • 詳解PHP序列化和反序列化原理
  • php中序列化與反序列化詳解
  • PHP中的串行化變量和序列化對(duì)象
  • PHP多種序列化/反序列化的方法詳解

標(biāo)簽:溫州 安康 紹興 清遠(yuǎn) 金華 呼倫貝爾 綏化 萊蕪

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《PHP序列化的四種實(shí)現(xiàn)方法與橫向?qū)Ρ取?,本文關(guān)鍵詞  PHP,序列化,的,四種,實(shí)現(xiàn),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《PHP序列化的四種實(shí)現(xiàn)方法與橫向?qū)Ρ取废嚓P(guān)的同類信息!
  • 本頁(yè)收集關(guān)于PHP序列化的四種實(shí)現(xiàn)方法與橫向?qū)Ρ鹊南嚓P(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章