溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么在PHP中實(shí)現(xiàn)序列化

發(fā)布時(shí)間:2021-05-14 17:04:32 來源:億速云 閱讀:172 作者:Leah 欄目:開發(fā)技術(shù)

今天就跟大家聊聊有關(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

怎么在PHP中實(shí)現(xiàn)序列化

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中實(shí)現(xiàn)序列化

php的框架有哪些

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è)資訊頻道,感謝大家的支持。

向AI問一下細(xì)節(jié)

免責(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)容。

php
AI