php serialize取值,PHP 序列化(serialize)格式详解
PHP
序列化(serialize)格式詳解(轉)
1.前言
PHP (從 PHP 3.05
開始)為保存對象提供了一組序列化和反序列化的函數:serialize、unserialize。不過在
PHP
手冊中對這兩個函數的說明僅限于如何使用,而對序列化結果的格式卻沒做任何說明。因此,這對在其他語言中實現
PHP
方式的序列化來說,就比較麻煩了。雖然以前也搜集了一些其他語言實現的
PHP
序列化的程序,不過這些實現都不完全,當序列化或反序列化一些比較復雜的對象時,就會出錯了。于是我決定寫一份關于
PHP
序列化格式詳解的文檔(也就是這一篇文檔),以便在編寫其他語言實現的
php
序列化程序時能有一個比較完整的參考。這篇文章中所寫的內容是我通過編寫程序測試和閱讀
PHP 源代碼得到的,所以,我不能 100%
保證所有的內容都是正確的,不過我會盡量保證我所寫下的內容的正確性,對于我還不太清楚的地方,我會在文中明確指出,也希望大家能夠給予補充和完善。
2.概述
PHP
序列化后的內容是簡單的文本格式,但是對字母大小寫和空白(空格、回車、換行等)敏感,而且字符串是按照字節(jié)(或者說是
8 位的字符)計算的,因此,更合適的說法是 PHP
序列化后的內容是字節(jié)流格式。因此用其他語言實現時,如果所實現的語言中的字符串不是字節(jié)儲存格式,而是
Unicode
儲存格式的話,序列化后的內容不適合保存為字符串,而應保存為字節(jié)流對象或者字節(jié)數組,否則在與
PHP 進行數據交換時會產生錯誤。
PHP 對不同類型的數據用不同的字母進行標示,Yahoo 開發(fā)網站提供的
Using Serialized PHP with Yahoo! Web Services
一文中給出所有的字母標示及其含義:
a - array
b - boolean
d - double
i - integer
o - common object
r - reference
s - string
C - custom object
O - class
N - null
R - pointer reference
U - unicode string
N 表示的是 NULL,而 b、d、i、s
表示的是四種標量類型,目前其它語言所實現的 PHP
序列化程序基本上都實現了對這些類型的序列化和反序列化,不過有一些實現中對
s (字符串)的實現存在問題。
a、O 屬于最常用的復合類型,大部分其他語言的實現都很好的實現了對 a
的序列化和反序列化,但對 O 只實現了 PHP4
中對象序列化格式,而沒有提供對 PHP 5
中擴展的對象序列化格式的支持。
r、R
分別表示對象引用和指針引用,這兩個也比較有用,在序列化比較復雜的數組和對象時就會產生帶有這兩個標示的數據,后面我們將詳細講解這兩個標示,目前這兩個標示尚沒有發(fā)現有其他語言的實現。
C 是 PHP5
中引入的,它表示自定義的對象序列化方式,盡管這對于其它語言來說是沒有必要實現的,因為很少會用到它,但是后面還是會對它進行詳細講解的。
U 是 PHP6 中才引入的,它表示 Unicode 編碼的字符串。因為 PHP6
中提供了 Unicode
方式保存字符串的能力,因此它提供了這種序列化字符串的格式,不過這個類型
PHP5、PHP4
都不支持,而這兩個版本目前是主流,因此在其它語言實現該類型時,不推薦用它來進行序列化,不過可以實現它的反序列化過程。在后面我也會對它的格式進行說明。
最后還有一個
o,這也是我唯一還沒弄清楚的一個數據類型標示。這個標示在 PHP3
中被引入用來序列化對象,但是到了 PHP4 以后就被 O 取代了。在 PHP3
的源代碼中可以看到對 o 的序列化和反序列化與數組 a
基本上是一樣的。但是在 PHP4、PHP5 和 PHP6
的源代碼中序列化部分里都找不到它的影子,但是在這幾個版本的反序列化程序源代碼中卻都有對它的處理,不過把它處理成什么我還沒弄清楚。因此對它暫時不再作更多說明了。
3.NULL 和標量類型的序列化
NULL
和標量類型的序列化是最簡單的,也是構成符合類型序列化的基礎。這部分內容相信許多
PHP
開發(fā)者都已經熟知。如果您感覺已經掌握了這部分內容,可以直接跳過這一章。
3.1.NULL 的序列化
在 PHP 中,NULL 被序列化為:
N;
3.2.boolean 型數據的序列化
boolean 型數據被序列化為:
b:;
其中 為 0 或 1,當 boolean 型數據為 false
時, 為 0,否則為 1。
3.3.integer 型數據的序列化
integer 型數據(整數)被序列化為:
i:;
其中 為一個整型數,范圍為:-2147483648 到
2147483647。數字前可以有正負號,如果被序列化的數字超過這個范圍,則會被序列化為浮點數類型而不是整型。如果序列化后的數字超過這個范圍(PHP
本身序列化時不會發(fā)生這個問題),則反序列化時,將不會返回期望的數值。
3.4.double 型數據的序列化
double 型數據(浮點數)被序列化為:
d:;
其中 為一個浮點數,其范圍與 PHP
中浮點數的范圍一樣。可以表示成整數形式、浮點數形式和科學技術法形式。如果序列化無窮大數,則
為 INF,如果序列化負無窮大,則 為
-INF。序列化后的數字范圍超過 PHP
能表示的最大值,則反序列化時返回無窮大(INF),如果序列化后的數字范圍超過
PHP 所能表示的最小精度,則反序列化時返回 0。
3.5.string 型數據的序列化
string 型數據(字符串)被序列化為:
s::"";
其中 是 的長度,
是非負整數,數字前可以帶有正號(+)。
為字符串值,這里的每個字符都是單字節(jié)字符,其范圍與 ASCII 碼的 0 -
255
的字符相對應。每個字符都表示原字符含義,沒有轉義字符,
兩邊的引號("")是必須的,但不計算在 當中。這里的
相當于一個字節(jié)流,而
是這個字節(jié)流的字節(jié)個數。
4.簡單復合類型的序列化
PHP
中的復合類型有數組(array)和對象(object)兩種,本章主要介紹在簡單情況下這兩種類型數據的序列化格式。關于嵌套定義的復合類型和自定義序列化方式的對象的序列化格式將在后面的章節(jié)詳細討論。
4.1.數組的序列化
數組(array)通常被序列化為:
a::{
2>...}
其中 表示數組元素的個數,、
2>…… 表示數組下標,、
2>…… 表示與下標相對應的數組元素的值。
下標的類型只能是整型或者字符串型,序列化后的格式跟整型和字符串型數據序列化后的格式相同。
數組元素值可以是任意類型,其序列化后的格式與其所對應的類型序列化后的格式相同。
4.2.對象的序列化
對象(object)通常被序列化為:
O::""::{
1>
2>...}
其中 表示對象的類名
的字符串長度。
表示對象中的字段1個數。這些字段包括在對象所在類及其祖先類中用
var、public、protected 和 private 聲明的字段,但是不包括 static 和
const 聲明的靜態(tài)字段。也就是說只有實例(instance)字段。
、……
n>表示每個字段的字段名,而 、
value 2>……
則表示與字段名所對應的字段值。
字段名是字符串型,序列化后格式與字符串型數據序列化后的格式相同。
字段值可以是任意類型,其序列化后的格式與其所對應的類型序列化后的格式相同。
但字段名的序列化與它們聲明的可見性是有關的,下面重點討論一下關于字段名的序列化。
4.3.對象字段名的序列化
var 和 public
聲明的字段都是公共字段,因此它們的字段名的序列化格式是相同的。公共字段的字段名按照聲明時的字段名進行序列化,但序列化后的字段名中不包括聲明時的變量前綴符號
$。
protected
聲明的字段為保護字段,在所聲明的類和該類的子類中可見,但在該類的對象實例中不可見。因此保護字段的字段名在序列化時,字段名前面會加上
0*0
的前綴。這里的 0 表示 ASCII 碼為 0 的字符,而不是 0 組合。
private
聲明的字段為私有字段,只在所聲明的類中可見,在該類的子類和該類的對象實例中均不可見。因此私有字段的字段名在序列化時,字段名前面會加上
00
的前綴。這里
表示的是聲明該私有字段的類的類名,而不是被序列化的對象的類名。因為聲明該私有字段的類不一定是被序列化的對象的類,而有可能是它的祖先類。
字段名被作為字符串序列化時,字符串值中包括根據其可見性所加的前綴。字符串長度也包括所加前綴的長度。其中
0 字符也是計算長度的。
總結
以上是生活随笔為你收集整理的php serialize取值,PHP 序列化(serialize)格式详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java jfinal 定时任务_JFi
- 下一篇: php 批量压缩png,利用Python