溫馨提示×

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

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

如何將串行化的變量轉(zhuǎn)化成PHP原始的變量值

發(fā)布時(shí)間:2021-11-02 11:25:51 來(lái)源:億速云 閱讀:113 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容主要講解“如何將串行化的變量轉(zhuǎn)化成PHP原始的變量值”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“如何將串行化的變量轉(zhuǎn)化成PHP原始的變量值”吧!

  在PHP中有多串行化處理的函數(shù):serialize(),該函數(shù)把任何變量值(除了資源變量)轉(zhuǎn)化為字符串的形式,可以把字符串保存到文件里,或者注冊(cè)為Session,乃至于使用curl來(lái)模擬GET/POST來(lái)傳輸變量,達(dá)到RPC的效果。

  如果要將串行化的變量轉(zhuǎn)化成PHP原始的變量值,那么可以使用unserialize()函數(shù)。

  一、變量串行化

  我們舉簡(jiǎn)單的例子來(lái)說(shuō)明串行化,以及它的存儲(chǔ)格式。

  整型:

  $var=23;

  echoserialize($var);

  輸出:

  i:23;

  浮點(diǎn)型:

  $var=1.23;

  echoserialize($var);

  輸出:

  d:1.229999999999999982236431605997495353221893310546875;

  字符串:

  $var="Thisisastring";

  echoserialize($var);

  $var="我是變量";

  echoserialize($var);

  輸出:

  s:16:"Thisisastring";

  s:8:"我是變量";

  布爾型:

  $var=true;

  echoserialize($var);

  $var=false;

  echoserialize($var);

  輸出:

  b:1;

  b:0;

  上面這些基本類(lèi)型串行化之后的情況很清楚,串行化之后的存儲(chǔ)格式是:

  變量類(lèi)型:[變量長(zhǎng)度:]變量值;

  就是第一位字符代表變量類(lèi)型,第二個(gè):代表分割,變量長(zhǎng)度是可選的,就是在字符串類(lèi)型里有,其他類(lèi)型沒(méi)有,最后一個(gè)就是變量值,每個(gè)串行化的值以";"作為結(jié)束。

  比如我們整型數(shù)字23串行化之后就是:i:23,那么它沒(méi)有長(zhǎng)度,只有類(lèi)型和變量值,i代表integer,通過(guò)冒號(hào)分割,后面保存的是整型值23,包括浮點(diǎn)型(雙字節(jié)型)也是一樣。布爾型的話(huà),類(lèi)型是b(boolean),如果是true的話(huà),那么串行化的值是1,如果是false那么值就是0。字

  符串值話(huà)中間會(huì)多一個(gè)保存的值得,保存字符串的長(zhǎng)度值,比如字符串"Thisisastring",那么生成的串行化的值是s:16:"Thisisastring";s是string,代表類(lèi)型,中間的16就是該字符串的長(zhǎng)度,如果是中文的話(huà),那么每個(gè)中文是兩個(gè)字符來(lái)保存的,比如字符串"我是變量",生成的串行化值是:s:8:"我是變量";就是8個(gè)字符的長(zhǎng)度。

  下面我們重點(diǎn)來(lái)講一下數(shù)組變量串行化。

  數(shù)組變量:

  $var=array("abc","def","xyz","123");

  echoserialize($var);

  輸出:

  a:4:{i:0;s:3:"abc";i:1;s:3:"def";i:2;s:3:"xyz";i:3;s:3:"123";}

  就是把我的數(shù)組$var串行化得到的字符串值,我們的$var數(shù)組包括4個(gè)字符串元素,分別是"abc","def","xyz","123",我們來(lái)分析一下串行化后的數(shù)據(jù),為了簡(jiǎn)便起見(jiàn),我們把串行化的數(shù)據(jù)列成數(shù)組的樣式:

  a:4:

  {

  i:0;s:3:"abc";

  i:1;s:3:"def";

  i:2;s:3:"xyz";

  i:3;s:3:"123";

  }

  這樣排列就比較清晰了,看開(kāi)始的字符串:a:4:{...}首先第一個(gè)字符a保存的是變量類(lèi)型是array(數(shù)組)類(lèi)型,第二個(gè)4保存的是數(shù)組元素的個(gè)數(shù),一共有4個(gè),然后在{}之間數(shù)組元素的內(nèi)容。比如第一個(gè)數(shù)組元素:i:0;s:3:"abc";i代表是當(dāng)前數(shù)組元素的索引值類(lèi)型是整型,并且值是0,元素值的類(lèi)型是s(字符串的),個(gè)數(shù)是3個(gè),具體值是"abc",分號(hào)結(jié)束,下面的數(shù)組元素依次類(lèi)推。

  我們?cè)倏纯词褂米址鰹樵厮饕龝?huì)如何:

  $var=array("index1"=>"abc","index2"=>"def","index3"=>"xyz","index4"=>"123");

  echoserialize($var);

  輸出:

  a:4:{s:6:"index1";s:3:"abc";s:6:"index2";s:3:"def";s:6:"index3";s:3:"xyz";s:6:"index4";s:3:"123";}

  變成數(shù)組樣式后:

  a:4:

  {

  s:6:"index1";s:3:"abc";

  s:6:"index2";s:3:"def";

  s:6:"index3";s:3:"xyz";

  s:6:"index4";s:3:"123";

  }

  其實(shí)跟上面沒(méi)有太大區(qū)別,不過(guò)是開(kāi)始的索引變成了保存字符串的形式,比如第一個(gè)元素:s:6:"index1";s:3:"abc";第一項(xiàng)就是索引值:s:6:"index1";s是類(lèi)型,6是索引字符串的長(zhǎng)度,"index1"就是索引的值。后面的s:3:"abc";就是元素值,這個(gè)好理解,就不講了。

  從上面來(lái)看,我們大致了解了基本數(shù)據(jù)類(lèi)型的串行化,其實(shí)我們完全可以構(gòu)造自己的串行化功能,或者從這個(gè)角度去擴(kuò)展,開(kāi)發(fā)自己的串行化程序,便于我們的變量交換。

  當(dāng)然,其實(shí)我們也可以利用這個(gè)功能,把數(shù)組或者任意其他變量串行化成字符串,然后通過(guò)curl功能來(lái)模擬GET/POST功能,達(dá)到能夠無(wú)用用戶(hù)執(zhí)行動(dòng)作就從遠(yuǎn)程服務(wù)器獲取數(shù)據(jù)的功能。

  怎樣將串行化的變量轉(zhuǎn)化成PHP原始的變量值

  二、對(duì)象序列化

  對(duì)象的序列化也是一個(gè)比較普遍的功能,能夠把一個(gè)對(duì)象進(jìn)行串行化以后變成一個(gè)字符串,能夠保存或者傳輸。

  我們先看一個(gè)例子:

  classTestClass

  {

  var$a;

  var$b;

  functionTestClass()

  {

  $this->a="Thisisa";

  $this->b="Thisisb";

  }

  functiongetA()

  {

  return$this->a;

  }

  functiongetB()

  {

  return$this->b;

  }

  }

  $obj=newTestClass;

  $str=serialize($obj);

  echo$str;

  輸出結(jié)果:

  O:9:"TestClass":2:{s:1:"a";s:9:"Thisisa";s:1:"b";s:9:"Thisisb";}

  我們來(lái)分析一個(gè)對(duì)象串行化之后的字符串。

  O:9:"TestClass":2:

  {

  s:1:"a";s:9:"Thisisa";

  s:1:"b";s:9:"Thisisb";

  }

  首先看對(duì)于對(duì)象本身的內(nèi)容:O:9:"TestClass":2:O是說(shuō)明這是一個(gè)對(duì)象類(lèi)型(object),然后9是代表對(duì)象的名字查過(guò)濃度,2是代表該對(duì)象有幾個(gè)屬性。在看兩個(gè)屬性的內(nèi)容:

  s:1:"a";s:9:"Thisisa";其實(shí)跟數(shù)組的內(nèi)容比較類(lèi)似,第一項(xiàng):s:1:"a";是描述屬性名稱(chēng)的,第二項(xiàng)s:9:"Thisisa";是描述屬性值的。后面的屬性類(lèi)似。

  先說(shuō)一種對(duì)象序列化的應(yīng)用,下面的內(nèi)容是PHP手冊(cè)上,沒(méi)有更改原文。

  serialize()返回一個(gè)字符串,包含著可以?xún)?chǔ)存于PHP的任何值的字節(jié)流表示。unserialize()可以用此字符串來(lái)重建原始的變量值。用序列化來(lái)保存對(duì)象可以保存對(duì)象中的所有變量。對(duì)象中的函數(shù)不會(huì)被保存,只有類(lèi)的名稱(chēng)。

  要能夠unserialize()一個(gè)對(duì)象,需要定義該對(duì)象的類(lèi)。也就是,如果序列化了page1.php中類(lèi)A的對(duì)象$a,將得到一個(gè)指向類(lèi)A的字符串并包含有所有$a中變量的值。如果要在page2.php中將其解序列化,重建類(lèi)A的對(duì)象$a,則page2.php中必須要出現(xiàn)類(lèi)A的定義。這可以例如這樣實(shí)現(xiàn),將類(lèi)A的定義放在一個(gè)包含文件中,并在page1.php和page2.php都包含此文件。

  //classa.inc:

  classA

  {

  var$one=1;

  functionshow_one()

  {

  echo$this->one;

  }

  }

  //page1.php:

  include("classa.inc");

  $a=newA;

  $s=serialize($a);

  //將$s存放在某處使page2.php能夠找到

  $fp=fopen("store","w");

  fputs($fp,$s);

  fclose($fp);

  //page2.php:

  //為了正常解序列化需要這一行

  include("classa.inc");

  $s=implode("",@file("store"));

  $a=unserialize($s);

  //現(xiàn)在可以用$a對(duì)象的show_one()函數(shù)了

  $a->show_one();

  ?>

  如果在用會(huì)話(huà)并使用了session_register()來(lái)注冊(cè)對(duì)象,這些對(duì)象會(huì)在每個(gè)PHP頁(yè)面結(jié)束時(shí)被自動(dòng)序列化,并在接下來(lái)的每個(gè)頁(yè)面中自動(dòng)解序列化?;旧鲜钦f(shuō)這些對(duì)象一旦成為會(huì)話(huà)的一部分,就能在任何頁(yè)面中出現(xiàn)。

  強(qiáng)烈建議在所有的頁(yè)面中都包括這些注冊(cè)的對(duì)象的類(lèi)的定義,即使并不是在所有的頁(yè)面中都用到了這些類(lèi)。如果沒(méi)有這樣做,一個(gè)對(duì)象被解序列化了但卻沒(méi)有其類(lèi)的定義,它將失去與之關(guān)聯(lián)的類(lèi)并成為stdClass的一個(gè)對(duì)象而完全沒(méi)有任何可用的函數(shù),這樣就很沒(méi)有用處。

  因此如果在以上的例子中$a通過(guò)運(yùn)行session_register("a")成為了會(huì)話(huà)的一部分,應(yīng)該在所有的頁(yè)面中包含classa.inc文件,而不只是page1.php和page2.php。

  當(dāng)然,其實(shí)序列化對(duì)象其實(shí)完全可以應(yīng)用在很多地方。當(dāng)然,在PHP5中對(duì)序列化的處理不一樣了,我們看一下手冊(cè)中的說(shuō)法:

  serialize()檢查類(lèi)中是否有魔術(shù)名稱(chēng)__sleep的函數(shù)。如果這樣,該函數(shù)將在任何序列化之前運(yùn)行。它可以清除對(duì)象并應(yīng)該返回一個(gè)包含有該對(duì)象中應(yīng)被序列化的所有變量名的數(shù)組。

  使用__sleep的目的是關(guān)閉對(duì)象可能具有的任何數(shù)據(jù)庫(kù)連接,提交等待中的數(shù)據(jù)或進(jìn)行類(lèi)似的清除任務(wù)。此外,如果有非常大的對(duì)象而并不需要完全儲(chǔ)存下來(lái)時(shí)此函數(shù)也很有用。

  相反地,unserialize()檢查具有魔術(shù)名稱(chēng)__wakeup的函數(shù)的存在。如果存在,此函數(shù)可以重建對(duì)象可能具有的任何資源。

  使用__wakeup的目的是重建在序列化中可能丟失的任何數(shù)據(jù)庫(kù)連接以及處理其它重新初始化的任務(wù)。

到此,相信大家對(duì)“如何將串行化的變量轉(zhuǎn)化成PHP原始的變量值”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(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