亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: PHP中的串行化變量和序列化對(duì)象 [打印本頁]

作者: rainbutterfly    時(shí)間: 2007-08-08 11:01
標(biāo)題: PHP中的串行化變量和序列化對(duì)象
串行化大概就是把一些變量轉(zhuǎn)化成為字符串的字節(jié)流的形式,這樣比較容易傳輸、存儲(chǔ)。當(dāng)然,關(guān)是傳輸存儲(chǔ)沒有什么,關(guān)鍵是變成串的形式以后還能夠轉(zhuǎn)化回來,而且能夠保持原來數(shù)據(jù)的結(jié)構(gòu)。
  在PHP中有多串行化處理的函數(shù):serialize(),該函數(shù)把任何變量值(除了資源變量)轉(zhuǎn)化為字符串的形式,可以把字符串保存到文件里,或者注冊(cè)為Session,乃至于使用curl來模擬GET/POST來傳輸變量,達(dá)到RPC的效果。
  如果要將串行化的變量轉(zhuǎn)化成PHP原始的變量值,那么可以使用unserialize()函數(shù)。
  一、變量串行化
  我們舉簡(jiǎn)單的例子來說明串行化,以及它的存儲(chǔ)格式。
  整型:
  $var = 23;
  echo serialize($var);
  輸出:
  i:23;
  浮點(diǎn)型:
  $var = 1.23;
  echo serialize($var);
  輸出:
  d:1.229999999999999982236431605997495353221893310546875;
  字符串:
  $var = "This is a string";
  echo serialize($var);
  $var = "我是變量";
  echo serialize($var);
  輸出:
  s:16:"This is a string";
  s:8:"我是變量";
  布爾型:
  $var = true;
  echo serialize($var);
  $var = false;
  echo serialize($var);
  輸出:
  b:1;
  b:0;
  上面這些基本類型串行化之后的情況很清楚,串行化之后的存儲(chǔ)格式是:
  變量類型:[變量長(zhǎng)度:]變量值;
  就是第一位字符代表變量類型,第二個(gè):代表分割,變量長(zhǎng)度是可選的,就是在字符串類型里有,其他類型沒有,最后一個(gè)就是變量值,每個(gè)串行化的值以";"作為結(jié)束。
  比如我們整型數(shù)字23串行化之后就是:i:23,那么它沒有長(zhǎng)度,只有類型和變量值,i代表integer,通過冒號(hào)分割,后面保存的是整型值
23,包括浮點(diǎn)型(雙字節(jié)型)也是一樣。布爾型的話,類型是b(boolean),如果是true的話,那么串行化的值是1,如果是false那么值就是
0。字
  符串值話中間會(huì)多一個(gè)保存的值得,保存字符串的長(zhǎng)度值,比如字符串"This is a string",那么生成的串行化的值是
s:16:"This is a string";
s是string,代表類型,中間的16就是該字符串的長(zhǎng)度,如果是中文的話,那么每個(gè)中文是兩個(gè)字符來保存的,比如字符串
"我是變量",生成的串行化值是:s:8:"我是變量"; 就是8個(gè)字符的長(zhǎng)度。
  下面我們重點(diǎn)來講一下數(shù)組變量串行化。
  數(shù)組變量:
$var = array("abc", "def", "xyz", "123");
echo serialize($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",我們來分析一下串行化后的數(shù)據(jù),為了簡(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";
}
  這樣排列就比較清晰了,看開始的字符串:a:4:{...} 首先第一個(gè)字符a保存的是變量類型是array(數(shù)組)類型,第二個(gè) 4
保存的是數(shù)組元素的個(gè)數(shù),一共有4個(gè),然后在{}之間數(shù)組元素的內(nèi)容。比如第一個(gè)數(shù)組元素:i:0;s:3:"abc";
i代表是當(dāng)前數(shù)組元素的索引值類型是整型,并且值是 0,元素值的類型是s(字符串的),個(gè)數(shù)是 3
個(gè),具體值是"abc",分號(hào)結(jié)束,下面的數(shù)組元素依次類推。
  我們?cè)倏纯词褂米址鰹樵厮饕龝?huì)如何:
$var = array("index1"=>"abc", "index2"=>"def", "index3"=>"xyz", "index4"=>"123");
echo serialize($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í)跟上面沒有太大區(qū)別,不過是開始的索引變成了保存字符串的形式,比如第一個(gè)元素:s:6:"index1";s:3:"abc";第一項(xiàng)就
是索引值:s:6:"index1"; s是類型,6是索引字符串的長(zhǎng)度,"index1"就是索引的值。后面的s:3:"abc";
就是元素值,這個(gè)好理解,就不講了。
  從上面來看,我們大致了解了基本數(shù)據(jù)類型的串行化,其實(shí)我們完全可以構(gòu)造自己的串行化功能,或者從這個(gè)角度去擴(kuò)展,開發(fā)自己的串行化程序,便于我們的變量交換。
  當(dāng)然,其實(shí)我們也可以利用這個(gè)功能,把數(shù)組或者任意其他變量串行化成字符串,然后通過curl功能來模擬GET/POST功能,達(dá)到能夠無用用戶執(zhí)行動(dòng)作就從遠(yuǎn)程服務(wù)器獲取數(shù)據(jù)的功能。
  二、對(duì)象序列化
  對(duì)象的序列化也是一個(gè)比較普遍的功能,能夠把一個(gè)對(duì)象進(jìn)行串行化以后變成一個(gè)字符串,能夠保存或者傳輸。
  我們先看一個(gè)例子:
class TestClass
{
 var $a;
 var $b;
 function TestClass()
 {
  $this->a = "This is a";
  $this->b = "This is b";
 }
 function getA()
 {
  return $this->a;
 }
 function getB()
 {
  return $this->b;
 }
}
$obj = new TestClass;
$str = serialize($obj);
echo $str;
  輸出結(jié)果:
O:9:"TestClass":2:{s:1:"a";s:9:"This is a";s:1:"b";s:9:"This is b";}
  我們來分析一個(gè)對(duì)象串行化之后的字符串。
O:9:"TestClass":2:
{
 s:1:"a";s:9:"This is a";
 s:1:"b";s:9:"This is b";
}
  首先看對(duì)于對(duì)象本身的內(nèi)容:O:9:"TestClass":2:O是說明這是一個(gè)對(duì)象類型(object),然后9是代表對(duì)象的名字查過濃度,2是代表該對(duì)象有幾個(gè)屬性。在看兩個(gè)屬性的內(nèi)容:
  s:1:"a";s:9:"This is a"; 其實(shí)跟數(shù)組的內(nèi)容比較類似,第一項(xiàng):s:1:"a"; 是描述屬性名稱的,第二項(xiàng)s:9:"This is a"; 是描述屬性值的。后面的屬性類似。
  先說一種對(duì)象序列化的應(yīng)用,下面的內(nèi)容是PHP手冊(cè)上,沒有更改原文。
  serialize() 返回一個(gè)字符串,包含著可以儲(chǔ)存于 PHP 的任何值的字節(jié)流表示。unserialize() 可以用此字符串來重建原始的變量值。用序列化來保存對(duì)象可以保存對(duì)象中的所有變量。對(duì)象中的函數(shù)不會(huì)被保存,只有類的名稱。
  要能夠 unserialize() 一個(gè)對(duì)象,需要定義該對(duì)象的類。也就是,如果序列化了 page1.php 中類 A 的對(duì)象
$a,將得到一個(gè)指向類 A 的字符串并包含有所有 $a 中變量的值。如果要在 page2.php 中將其解序列化,重建類 A 的對(duì)象 $a,則
page2.php 中必須要出現(xiàn)類 A 的定義。這可以例如這樣實(shí)現(xiàn),將類 A 的定義放在一個(gè)包含文件中,并在 page1.php 和
page2.php 都包含此文件。
<?php
// classa.inc:
class A
{
 var $one = 1;
 function show_one()
 {
  echo $this->one;
 }
}
// page1.php:
include("classa.inc");
$a = new A;
$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ì)話并使用了 session_register() 來注冊(cè)對(duì)象,這些對(duì)象會(huì)在每個(gè) PHP 頁面結(jié)束時(shí)被自動(dòng)序列化,并在接下來的每個(gè)頁面中自動(dòng)解序列化;旧鲜钦f這些對(duì)象一旦成為會(huì)話的一部分,就能在任何頁面中出現(xiàn)。
  強(qiáng)烈建議在所有的頁面中都包括這些注冊(cè)的對(duì)象的類的定義,即使并不是在所有的頁面中都用到了這些類。如果沒有這樣做,一個(gè)對(duì)象被解序列化了但卻沒有其類的定義,它將失去與之關(guān)聯(lián)的類并成為 stdClass 的一個(gè)對(duì)象而完全沒有任何可用的函數(shù),這樣就很沒有用處。
  因此如果在以上的例子中 $a 通過運(yùn)行 session_register("a") 成為了會(huì)話的一部分,應(yīng)該在所有的頁面中包含 classa.inc 文件,而不只是page1.php 和 page2.php。
  當(dāng)然,其實(shí)序列化對(duì)象其實(shí)完全可以應(yīng)用在很多地方。當(dāng)然,在PHP 5中對(duì)序列化的處理不一樣了,我們看一下手冊(cè)中的說法:
  serialize() 檢查類中是否有魔術(shù)名稱 __sleep 的函數(shù)。如果這樣,該函數(shù)將在任何序列化之前運(yùn)行。它可以清除對(duì)象并應(yīng)該返回一個(gè)包含有該對(duì)象中應(yīng)被序列化的所有變量名的數(shù)組。
  使用 __sleep 的目的是關(guān)閉對(duì)象可能具有的任何
數(shù)據(jù)庫
連接,提交等待中的數(shù)據(jù)或進(jìn)行類似的清除任務(wù)。此外,如果有非常大的對(duì)象而并不需要完全儲(chǔ)存下來時(shí)此函數(shù)也很有用。
  相反地,unserialize() 檢查具有魔術(shù)名稱 __wakeup 的函數(shù)的存在。如果存在,此函數(shù)可以重建對(duì)象可能具有的任何資源。
  使用 __wakeup 的目的是重建在序列化中可能丟失的任何數(shù)據(jù)庫連接以及處理其它重新初始化的任務(wù)。
               
               
               

本文來自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u/27402/showart_355906.html




歡迎光臨 Chinaunix (http://www.72891.cn/) Powered by Discuz! X3.2