首頁 php教程 php手册 PHP中的串行化变量和序列化对象

PHP中的串行化变量和序列化对象

Jun 13, 2016 pm 12:46 PM
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 的目的是重建在序列化中可能丢失的任何数据库连接以及处理其它重新初始化的任务。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1426
52
Laravel 教程
1328
25
PHP教程
1273
29
C# 教程
1253
24
PHP和Python:比較兩種流行的編程語言 PHP和Python:比較兩種流行的編程語言 Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP行動:現實世界中的示例和應用程序 PHP行動:現實世界中的示例和應用程序 Apr 14, 2025 am 12:19 AM

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP與Python:了解差異 PHP與Python:了解差異 Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP的持久相關性:它還活著嗎? PHP的持久相關性:它還活著嗎? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP與其他語言:比較 PHP與其他語言:比較 Apr 13, 2025 am 12:19 AM

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

PHP和Python:代碼示例和比較 PHP和Python:代碼示例和比較 Apr 15, 2025 am 12:07 AM

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

See all articles