一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

PHP中的串行化變量和序列化對象

  串行化大概就是把一些變量轉化成為字符串的字節流的形式,這樣比較容易傳輸、存儲。當然,關是傳輸存儲沒有什么,關鍵是變成串的形式以后還能夠轉化回來,而且能夠保持原來數據的結構。

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

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

  一、變量串行化

  我們舉簡單的例子來說明串行化,以及它的存儲格式。

  整型:

  $var = 23;
  echo serialize($var);

  輸出:

  i:23;

  浮點型:

  $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;

  上面這些基本類型串行化之后的情況很清楚,串行化之后的存儲格式是:

  變量類型:[變量長度:]變量值;

  就是第一位字符代表變量類型,第二個:代表分割,變量長度是可選的,就是在字符串類型里有,其他類型沒有,最后一個就是變量值,每個串行化的值以";"作為結束。

  比如我們整型數字23串行化之后就是:i:23,那么它沒有長度,只有類型和變量值,i代表integer,通過冒號分割,后面保存的是整型值23,包括浮點型(雙字節型)也是一樣。布爾型的話,類型是b(boolean),如果是true的話,那么串行化的值是1,如果是false那么值就是0。字

  符串值話中間會多一個保存的值得,保存字符串的長度值,比如字符串"This is a string",那么生成的串行化的值是 s:16:"This is a string"; s是string,代表類型,中間的16就是該字符串的長度,如果是中文的話,那么每個中文是兩個字符來保存的,比如字符串 "我是變量",生成的串行化值是:s:8:"我是變量"; 就是8個字符的長度。

  下面我們重點來講一下數組變量串行化。

  數組變量:

$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";}

  就是把我的數組 $var 串行化得到的字符串值,我們的$var數組包括4個字符串元素,分別是"abc", "def", "xyz", "123",我們來分析一下串行化后的數據,為了簡便起見,我們把串行化的數據列成數組的樣式:

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

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

  我們再看看使用字符串做為元素索引會如何:

$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";}

  變成數組樣式后:

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";
}

  其實跟上面沒有太大區別,不過是開始的索引變成了保存字符串的形式,比如第一個元素:s:6:"index1";s:3:"abc";第一項就是索引值:s:6:"index1"; s是類型,6是索引字符串的長度,"index1"就是索引的值。后面的s:3:"abc"; 就是元素值,這個好理解,就不講了。

  從上面來看,我們大致了解了基本數據類型的串行化,其實我們完全可以構造自己的串行化功能,或者從這個角度去擴展,開發自己的串行化程序,便于我們的變量交換。

  當然,其實我們也可以利用這個功能,把數組或者任意其他變量串行化成字符串,然后通過curl功能來模擬GET/POST功能,達到能夠無用用戶執行動作就從遠程服務器獲取數據的功能。

  二、對象序列化

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

  我們先看一個例子:

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;

  輸出結果:

O:9:"TestClass":2:{s:1:"a";s:9:"This is a";s:1:"b";s:9:"This is b";}

  我們來分析一個對象串行化之后的字符串。

O:9:"TestClass":2:
{
 s:1:"a";s:9:"This is a";
 s:1:"b";s:9:"This is b";
}

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

  s:1:"a";s:9:"This is a"; 其實跟數組的內容比較類似,第一項:s:1:"a"; 是描述屬性名稱的,第二項s:9:"This is a"; 是描述屬性值的。后面的屬性類似。

  先說一種對象序列化的應用,下面的內容是php手冊上,沒有更改原文。

  serialize() 返回一個字符串,包含著可以儲存于 php 的任何值的字節流表示。unserialize() 可以用此字符串來重建原始的變量值。用序列化來保存對象可以保存對象中的所有變量。對象中的函數不會被保存,只有類的名稱。

  要能夠 unserialize() 一個對象,需要定義該對象的類。也就是,如果序列化了 page1.php 中類 A 的對象 $a,將得到一個指向類 A 的字符串并包含有所有 $a 中變量的值。如果要在 page2.php 中將其解序列化,重建類 A 的對象 $a,則 page2.php 中必須要出現類 A 的定義。這可以例如這樣實現,將類 A 的定義放在一個包含文件中,并在 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);

// 現在可以用 $a 對象的 show_one() 函數了
$a->show_one();
?>

  如果在用會話并使用了 session_register() 來注冊對象,這些對象會在每個 php 頁面結束時被自動序列化,并在接下來的每個頁面中自動解序列化。基本上是說這些對象一旦成為會話的一部分,就能在任何頁面中出現。

  強烈建議在所有的頁面中都包括這些注冊的對象的類的定義,即使并不是在所有的頁面中都用到了這些類。如果沒有這樣做,一個對象被解序列化了但卻沒有其類的定義,它將失去與之關聯的類并成為 stdClass 的一個對象而完全沒有任何可用的函數,這樣就很沒有用處。

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

  當然,其實序列化對象其實完全可以應用在很多地方。當然,在php 5中對序列化的處理不一樣了,我們看一下手冊中的說法:

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

  使用 __sleep 的目的是關閉對象可能具有的任何數據庫連接,提交等待中的數據或進行類似的清除任務。此外,如果有非常大的對象而并不需要完全儲存下來時此函數也很有用。

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

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

php技術PHP中的串行化變量和序列化對象,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 国产美女视频 | 久久夜色精品国产欧美 | 国产精品女人在线观看 | 色网视频在线观看 | 一区二区美女视频 | 久久亚洲精品无码观看不卡 | 色优优影院 | 国产免费一区二区三区最新 | 91在线免费视频 | 亚洲第一综合网站 | 丁香六月综合网 | 国产福利在线免费观看 | 亚洲欧美日韩精品香蕉 | 欧美特黄一片aa大片免费看 | 国产精品一区二区三区免费 | 美女一级毛片毛片在线播放 | 91短视频网址 | 婷婷激情五月 | 亚洲综合激情九月婷婷 | 亚洲 欧美 在线观看 | 国产日韩欧美二区 | 国产精品视频区 | 五月婷婷丁香色 | xfplay影音先锋永久资源 | 日本韩国视频 | 色哟哟精品视频在线观看 | 精品国产一区二区三区在线观看 | 午夜国产在线视频 | 激情区 | 亚洲一区二区三区高清 | 亚洲一区二区中文字幕 | 免费黄色视屏网站 | 在线永久免费观看黄网站 | 美女视频网 | 天堂成人精品视频在线观 | 天天舔天天色 | 91网站国产 | 精品视频免费在线观看 | 怡红院在线视频精品观看 | 国产午夜在线观看 | 五月天丁香六月欧美综合 |