内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

PHP序列化和反序列化原理是什么-創(chuàng)新互聯(lián)

創(chuàng)新互聯(lián)www.cdcxhl.cn八線動態(tài)BGP香港云服務(wù)器提供商,新人活動買多久送多久,劃算不套路!

迪慶州ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!

PHP序列化和反序列化原理是什么?相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

0.前言

對象的序列化和反序列化作用就不再贅述,php中序列化的結(jié)果是一個php自定義的字符串格式,有點類似json.

我們在任何語言中設(shè)計對象的序列化和反序列化都需要解決幾個問題

把某個對象序列化之后,序列化的結(jié)果有自描述的功能(從序列化的結(jié)果中知道這個對象的具體類型,

知道類型還不夠,當(dāng)然還需要知道這個類型所對應(yīng)具體的值).

序列化時的權(quán)限控制,可以自定義序列化字段等,例如golang中的做的就非常方便.

時間性能問題:在某些性能敏感的場景下,對象序列化就不能拖后腿,例如:高性能服務(wù)(我經(jīng)常使用protobuf來序列化).

空間性能問題:序列化之后的結(jié)果不能太長,比如內(nèi)存中一個int對象,序列化之后數(shù)據(jù)長度變成了10倍int的長度,那這個序列化算法是有問題的.

本文僅僅從php代碼角度來解釋php中序列化和反序列化的過程.,記住一點序列化和反序列化操作的僅僅是對象的數(shù)據(jù),這一點有面向?qū)ο箝_發(fā)經(jīng)驗的都應(yīng)該容易理解.

1.序列化serialize和反序列化方法unserialize

php原生提供了對象序列化功能,不像c++ ……^_^. 用起來也非常簡單,就兩個接口.

class fobnn
{
 public $hack_id;
 private $hack_name;
 public function __construct($name,$id)
 {
  $this->hack_name = $name;
  $this->hack_id = $id;
 }
 public function print()
 {
  echo $this->hack_name.PHP_EOL;
 }
}
$obj = new fobnn('fobnn',1);
$obj->print();
$serializedstr = serialize($obj); //通過serialize接口序列化
echo $serializedstr.PHP_EOL;;
$toobj = unserialize($serializedstr);//通過unserialize反序列化
$toobj->print();
fobnn
O:5:"fobnn":2:{s:7:"hack_id";i:1;s:16:"fobnnhack_name";s:5:"fobnn";}
fobnn

看到第二行的輸出,這個字符串就是序列化的結(jié)果,這個結(jié)構(gòu)其實很容讀懂,可以發(fā)現(xiàn)是通過對象名稱/成員名稱來映射的,當(dāng)然不同訪問權(quán)限的成員序列化之后的標(biāo)簽名稱略有不同.

根據(jù)我上面講到的3個問題,那么我們可以來看看

1.自描述功能

O:5:"fobnn":2 其中o就表示了object類型,且類型名稱為fobnn, 采用這種格式,后面的2表示了有2個成員對象.

關(guān)于成員對象,其實也是同一套子描述,這是一個遞歸的定義.

自描述的功能主要是通過字符串記錄對象和成員的名稱來實現(xiàn).

2.性能問題

php序列化的時間性能本文就不分析了,詳見后面,但序列化結(jié)果其實類似json/bson定義的協(xié)議,有協(xié)議頭,協(xié)議頭說明了類型,協(xié)議體則說明了類型所對應(yīng)的值,并不會對序列化結(jié)果進(jìn)行壓縮.

2.反序列化中的魔術(shù)方法

對應(yīng)上述說的第二個問題,其實php中也有解決方法,一種是通過魔術(shù)方法,第二種則是自定義序列化函數(shù).先來介紹下魔術(shù)方法 __sleep和__wakeup

class fobnn
{
 public $hack_id;
 private $hack_name;
 public function __construct($name,$id)
 {
  $this->hack_name = $name;
  $this->hack_id = $id;
 }
 public function print()
 {
  echo $this->hack_name.PHP_EOL;
 }
 public function __sleep()
 {
  return array("hack_name");
 }
 public function __wakeup()
 {
  $this->hack_name = 'haha';
 }
}
$obj = new fobnn('fobnn',1);
$obj->print();
$serializedstr = serialize($obj);
echo $serializedstr.PHP_EOL;;
$toobj = unserialize($serializedstr);
$toobj->print();
fobnn
O:5:"fobnn":1:{s:16:"fobnnhack_name";s:5:"fobnn";}
haha

在序列化之前會先調(diào)用__sleep返回的是一個需要序列化的成員名稱數(shù)組,通過這樣我們就可以控制需要序列化的數(shù)據(jù),案例中我只返回了hack_name,可以看到結(jié)果中只序列化了hack_name成員.

在序列化完成之后,會跳用__wakeup在這里我們可以做一些后續(xù)工作,例如重連數(shù)據(jù)庫之類的.

3.自定義Serializable接口

interface Serializable {
abstract public string serialize ( void )
abstract public void unserialize ( string $serialized )
}

通過這個接口我們可以自定義序列化和反序列化的行為,這個功能主要可以用來自定義我們的序列化格式.

class fobnn implements Serializable
{
 public $hack_id;
 private $hack_name;
 public function __construct($name,$id)
 {
  $this->hack_name = $name;
  $this->hack_id = $id;
 }
 public function print()
 {
  echo $this->hack_name.PHP_EOL;
 }

 public function __sleep()
 {
  return array('hack_name');
 }

 public function __wakeup()
 {
  $this->hack_name = 'haha';
 }

 public function serialize()
 {
  return json_encode(array('id' => $this->hack_id ,'name'=>$this->hack_name ));
 }

 public function unserialize($var)
 {
  $array = json_decode($var,true);
  $this->hack_name = $array['name'];
  $this->hack_id = $array['id'];
 }
}
$obj = new fobnn('fobnn',1);
$obj->print();
$serializedstr = serialize($obj);
echo $serializedstr.PHP_EOL;;
$toobj = unserialize($serializedstr);
$toobj->print();
fobnn
C:5:"fobnn":23:{{"id":1,"name":"fobnn"}}
fobnn

當(dāng)使用了自定義序列化接口之后,我們的魔術(shù)方法就沒用了.

4.PHP動態(tài)類型和PHP反序列化

既然上文中提到的自描述功能,那么序列化結(jié)果中保存了對象的類型,且php是動態(tài)類型語言,那么我們就可以來做個簡單的實驗.

class fobnn
{
 public $hack_id;
 public $hack_name;
 public function __construct($name,$id)
 {
  $this->hack_name = $name;
  $this->hack_id = $id;
 }
 public function print()
 {
  var_dump($this->hack_name);
 }
}
$obj = new fobnn('fobnn',1);
$obj->print();
$serializedstr = serialize($obj);
echo $serializedstr.PHP_EOL;;
$toobj = unserialize($serializedstr);
$toobj->print();
$toobj2 = unserialize("O:5:\"fobnn\":2:{s:7:\"hack_id\";i:1;s:9:\"hack_name\";i:12345;}");
$toobj2->print();

我們修改hack_name反序列化的結(jié)果為int類型, i:12345

string(5) "fobnn"
O:5:"fobnn":2:{s:7:"hack_id";i:1;s:9:"hack_name";s:5:"fobnn";}
string(5) "fobnn"
int(12345)

看完上述內(nèi)容,你們掌握PHP序列化和反序列化原理是什么的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝各位的閱讀!

文章名稱:PHP序列化和反序列化原理是什么-創(chuàng)新互聯(lián)
分享路徑:http://m.rwnh.cn/article22/ddodcc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設(shè)、虛擬主機(jī)、網(wǎng)站營銷、微信公眾號、營銷型網(wǎng)站建設(shè)、手機(jī)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運營
新余市| 徐水县| 崇阳县| 东台市| 长葛市| 景洪市| 红河县| 莆田市| 屏南县| 清镇市| 阿克| 壶关县| 新安县| 金乡县| 广饶县| 米泉市| 肇东市| 山东省| 崇阳县| 同仁县| 鄂托克旗| 邵东县| 龙海市| 西和县| 福贡县| 汉寿县| 奎屯市| 大城县| 阳曲县| 凤阳县| 屏边| 盐津县| 江川县| 和硕县| 临高县| 吴川市| 布尔津县| 承德市| 铜梁县| 盱眙县| 西华县|