久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      直擊PHP序列化和反序列化原理

      直擊PHP序列化和反序列化原理

      0.前言

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

      我們?cè)谌魏握Z(yǔ)言中設(shè)計(jì)對(duì)象的序列化和反序列化都需要解決幾個(gè)問題

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

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

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

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

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

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

      相關(guān)學(xué)習(xí)推薦:PHP編程從入門到精通

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

      php原生提供了對(duì)象序列化功能,不像c++ ……^_^. 用起來也非常簡(jiǎn)單,就兩個(gè)接口.

      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

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

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

      1.自描述功能

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

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

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

      2.性能問題

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

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

      對(duì)應(yīng)上述說的第二個(gè)問題,其實(shí)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

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

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

      3.自定義Serializable接口

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

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

      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動(dòng)態(tài)類型和PHP反序列化

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

      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)

      可以發(fā)現(xiàn),對(duì)象成功序列化回來了!并且可以正常工作!. 當(dāng)然php的這種機(jī)制提供了靈活多變的語(yǔ)法,但也引入了安全風(fēng)險(xiǎn). 后續(xù)繼續(xù)分析php序列化和反序列化特性帶來的安全問題.

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)