03月19
做者:hanguofeng[小韓]
發佈於:經典論壇 玄貓的窩(做者的博客)
What 、Why、How
What
Ok,各位親愛的朋友,讓咱們開始這個新概念的旅程,串行化這個話題可能你們之前都沒有多加關注,事情其實起源於那天我隨便翻翻PHP手冊,發現這個串行化的函數,以後閒來無聊又作一個WordPress的插件,這個時候順便用了一下串行化,發如今某些場合的確很是方便。
先來解釋下串行化:簡單來講,串行化即將變量轉換成字節流的過程。串行化的提出,有效的解決了對象的保存和傳輸的問題,舉例來講,我在JavaScript中創建了一個對象,我如今想將這個對象保存到服務器端的數據庫中,那麼我如何進行操做呢,這個時候每每就用到了對象的串行化。在JavaScript的串行化中不得不提JSON,JSON(JavaScript
Object Notation) 是一種輕量級的數據交換格式。易於人閱讀和編寫,同時也易於機器解析和生成。它基於JavaScript Programming Language, Standard ECMA-262 3rd Edition - December
1999的一個子集。 JSON採用徹底獨立於語言的文本格式,可是也使用了相似於C語言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。這些特性使JSON成爲理想的數據交換語言。
人們一般將JSON和XML進行比較,兩者都是將對象扁平化(稍後咱們解釋這個」扁平化」)的一種手段,XML的特色是結構嚴謹,而JSON的特色則是簡單易讀、容易使用程序進行分析,由於它可以很簡單的將一個對象轉換爲一個字符流的形式,例如以下代碼:
-
{"type":"human","name":"hanguofeng","age":22}
則是一個JSON表達式,他保存了一個對象,咱們如何將它恢復爲對象呢?很簡單,以下:
-
var animal_str = '{"type":"human","name":"hanguofeng","age":22}';
-
-
咱們經過JavaScript的求值函數,將JSON表達式進行運算,並返回值,用以得到一個對象,到這裏,我想你必定會和我同樣,對JSON格式的創造者的思惟佩服不已吧。
-
-
原本說講串行化的,"不當心"談到JSON,而且講了這麼多,呵呵,跑題了嗎?沒有,PHP的串行化和JSON是很是像的,一個PHP的串行化表達式以下:
-
a:3:{s:4:"type";s:5:"human";s:4:"name";s:10:"hanguofeng";s:3:"age";s:2:"20";}
他看起來結構和JSON有些相似,實際上,這個表達式是以下數組的串行化結果:
-
$animal =
-
(
-
-
"type" => "human",
-
-
"name" => "hanguofeng",
-
-
"age" => "20"
-
-
);
OK,上面的一些介紹只是讓你大體看到串行化和JSON是什麼樣的東西,你無須對這裏的代碼過度糾結,咱們在後面會詳細講解的,下面咱們來談談爲何要使用串行化。
Why
串行化首先是做爲數據傳輸的方便而出現的,正如本文開始我提出的問題,我在JavaScript中創建了一個對象,我如今想將這個對象保存到服務器端的數據庫中,應該如何作,這其實上是一個」我如何將一個對象從瀏覽器提交到服務器」的問題,在這個傳輸過程當中,咱們知道,實際上只可以傳遞字符流,字符流是一維(扁平)的,然而不少對象倒是多維的,若是要傳遞的對象是一個字符串,那麼很簡單,咱們直接將其做爲傳遞的內容就能夠了,若是要傳遞的對象是一個數組或者其餘的結構呢,咱們就須要用字符流來描述他,就好比在電話裏面,我問你的名字是什麼,你會告訴我,你的名字是張3、李四,而我問你,你的長相如何呢,你就須要用文字向我描述了,咱們進行數據傳遞的媒介每每和這條電話線路同樣,只能傳遞字符流,而咱們描述對象的過程,實際上就是串行化的過程。
另外,串行化也能夠用於對對象的持久化存儲,也許你曾經也和我同樣,想着在數據庫的某一個字段中存儲一個對象,如今咱們能夠很是簡單的作到這一點,而且,你的這個數據庫字段不須要設定爲特殊格式,設定爲varchar就能夠了(固然,若是對象很大,你可能須要設定爲text)。
How
PHP串行化語法
好了,我想What和Why的問題你都瞭解了,本節最後咱們來說點理論性強一些的內容,就是如何使用PHP串行化和反串行化數據,如何將JavaScript對象串行化(即變爲JSON格式)和如何將其反串行化,最後則是如何將JSON和PHP的串行化創建關係。
PHP爲咱們提供了兩個函數,用來進行串行化和反串行化的操做,這兩個函數分別是:serialize()和unserialize(),他們適用於PHP4和PHP5,下面分別進行講解:
serialize()
(PHP 4, PHP 5, PECL axis2:0.1.0-0.1.1)
serialize - 得到一個可存儲的表述值
說明
string serialize ( mixed $value )
得到一個可存儲的表述值
本函數用於無損的存儲或者傳遞PHP變量值和結構。
若是須要將已經串行化的值轉回PHP變量,可使用unserialize()函數。
參數
value
即被串行化的表達式。serialize()處理除資源指針以外的全部類型,你甚至能夠將含有指向自身元素的數組串行化。你串行化的含有循環指向的數組或者對象同樣會被存儲,其餘的指向則會丟失。
當串行化對象時,PHP會嘗試首先調用其成員函數__sleep()。這將容許對象在被串行化以前進行諸如最後的清理工做等。一樣地,當使用unserialize()函數將對象恢復時,會調用成員函數__wakeup()。
返回值
返回一個能夠被存儲在任何地點的包含對象的字節流表達式的字符串。
unserialize()
(PHP 4, PHP 5, PECL axis2:0.1.0-0.1.1)
unserialize - 從一個已存儲的表達式中得到一個PHP變量值
說明
mixed unserialize ( string $str )
unserialize()獲取一個簡單類型的串行化變量並將其轉換回PHP變量值。
參數
str
串行化後的字符串
若是被反串行化的變量是一個對象,則成功恢復該對象的結構後,PHP將自動嘗試執行該對象的__wakeup()成員函數(若是其存在)。
unserialize_callback_func指令:你能夠設定在此過程當中唄執行的回調函數,若是某個未被定義的類應當在反串行化時被實例化(以免得到一個不徹底的對象」__PHP_Incomplete_Class」)。你可使用php.ini,ini_set()或者.htaccess來定義」unserialize_callback_func」。當一個未被定義的類被實例化時,它會被調用。屏蔽這個特性只需將其設爲空便可。
返回值
返回轉換後的數值,多是布爾變量、實數、浮點數、字符串、數組或者對象。
假如傳入的字符串不能夠被反串行化,則返回FALSE,同時拋出NOTICE錯誤。
(以上譯自PHP手冊)
PHP串行化實例
數組的串行化和反串行化
OK,讓咱們來用實例學習一下,首先,請創建sample1.php文件,咱們在這個文件中用以下語句來建立一個哈希數組:
-
$animal =
-
(
-
"type" => "human",
-
-
"name" => "hanguofeng",
-
-
"age" => "20"
-
-
);
爲了測試這個數組的值,你可使用print_r()函數來輸出數組,輸出的結果以下:
Array
(
[type] => human
[name] => hanguofeng
[age] => 20
)
那麼咱們將他來串行化一下,串行化的代碼以下:
$animal =
array
(
"type" => "human",
"name" => "hanguofeng",
"age" => "20"
);
$animal_ser=serialize($animal);
echo($animal_ser);
這裏咱們將數組$animal串行化,將返回的串行化字符串保存在變量$animal_ser中,並輸出,輸出的結果是:
a:3:{s:4:"type";s:5:"human";s:4:"name";s:10:"hanguofeng";s:3:"age";s:2:"20";}
咱們來簡單對這個字符串進行一個解析:
a:3表示這是一個數組型的對象(a),他共有三個內置的對象(3)
大括號裏面的部分是以逗號分割的對象表達式列表,以s:4:」type」爲例,他表示一個字符串(s),長度爲4位(4),值爲」type」,即哈希數組的第一個元素的鍵。
後面的部分以此類推,咱們再也不贅述,你能夠試試本身將各類對象串行化,看看串行化後的字符串是如何構建的。
下面來看數組的反串行化,即將咱們上面生成的串行化字符串恢復爲數組,代碼以下:
$animal_ser='a:3:{s:4:"type";s:5:"human";s:4:"name";s:10:"hanguofeng";s:3:"age";s:2:"20";}';
$animal = unserialize($animal_ser);
print_r($animal);
在第一行中,咱們假設$animal_ser的值爲上面得到的串行化字符串,在第二行將該字符串恢復爲開始的數組,並賦值給$animal,最後輸出$animal這個數組,此時的輸出和本節開始時輸出的原始數組是同樣的,即:
Array
(
[type] => human
[name] => hanguofeng
[age] => 20
)
這樣咱們就完成了數組的反串行化。
拓展知識-自定義對象的串行化和反串行化
對數組進行串行化是一個基礎操做,然而在實際的程序設計中,咱們可能常常對其餘類型的變量進行串行化,例如對某個自定義對象進行串行化,這裏有一個咱們本身編寫的類A(保存在classa.inc中):
class A {
var $one = 1;
function show_one() {
echo $this->one;
}
}
咱們在以下代碼中建立類的實例並對該實例進行串行化:
//省略引入classa.inc文件的代碼
$a=new A;
echo(serialize($a));
此時輸出的內容爲:
O:1:"A":1:{s:3:"one";i:1;}
整體來看,這個串行化字符串輸出了改對象當前的狀態,即i的值爲1。下面咱們來逐個分析其中的細節。
O:1:因爲當前的變量是一個自定義對象,所以該表徵字符爲」O」,表示Object。
後面的」A」標識了該變量是哪一個類的實例,這裏即A類。
大括號內即該實例的各個屬性的名稱和值。
然後咱們將其進行反串行化:
//省略引入classa.inc文件的代碼
include("classa.inc");
$s = 'O:1:"A":1:{s:3:"one";i:1;}';
$a = unserialize($s);
$a->show_one();
此時輸出」1″,即調用了A類的show_one()方法。
你能夠注意到雖然在實例的串行化字符串中並無包含類的方法,可是咱們將其反串行化後,仍然能夠調用類的方法,這個特性在PHP4及以上版本中被支持(固然,你須要包含類的定義文件classa.inc)。
注:你能夠參考PHP手冊中Language Reference->Classes and Objects->Serializing objects - objects in sessions一節的內容。
在JavaScript中串行化爲JSON-使用json2.js
JavaScript中沒有直接串行化對象的內置方法,固然你能夠本身寫一個,不過我仍是強烈推薦你在這裏偷個小懶,使用現成的組件,JSON的官方網站
「[url]http://www.json.org[/url]」>[url]www.json.org[/url]提供了對JavaScript對象實現JSON串行化的代碼庫-json2.js,你能夠從這裏得到它。
得到完畢json2.js文件後,你能夠打開這個文件,在文件的前部分包含了至關大量的註釋信息,若是你的英文足夠好,那麼你能夠省略我這一節,參考該文件的註釋就能夠了,若是做爲程序員,你已經看夠了大片的字母,想看看個人漢字+字母,那你能夠向下繼續了。
簡單的翻譯下這個註釋:
該文件建立了一個包含兩個方法的全局對象JSON,它的方法分別是:
JSON.stringify(value, whitelist)
value 任意的JavaScript值,通常是一個對象或者數組
whitelist 一個可選的數組參數,用於斷定對象值如何被串行化
這個方法經過一個JavaScript值來生成JSON文本。在進行串行化時,根據可選的參數whitelist,有三種可能:
若是某個對象有toJSON方法,那麼則調用該方法,toJSON方法的返回值將被串行化。
不然,若是可選參數whitelist是一個數組,那麼數組中的元素將被用來選擇對象進行串行化時的的成員。
不然,若是沒有使用whitelist參數,則對象的全部成員將被串行化。
若是值沒有JSON的表現形式,例如undefined或者函數,則其不會被串行化。在對象中,這樣的值會被忽略,而在數組中將會被null替換。
JSON.stringify(undefined)會返回undefined。日期將會被串行化爲被引用的ISO日期。
例:
var text = JSON.stringify(['e', {pluribus: 'unum'}]);
//text is '["e",{"pluribus":"unum"}]‘
JSON.parse(text, filter)
該方法解析一個JSON文本,並生成一個組件或者數組,其可能拋出一個SyntaxError異常。
可選的filter參數是一個可過濾和轉換結果的函數、它接受每一個鍵和值,它的返回值用來替換源值。若是它返回所接收的值,那麼結果不會被改變。若是他返回undefined,則該成員會被刪除。
例:
//解析文本,若是某個鍵包含字符串"date",則將其值轉換爲日期
myData = JSON.parse(text, function (key, value) {
return key.indexOf('date') >= 0 ? new Date(value) : value;
});
上面的入門教程已經使你基本瞭解了json2.js的使用方法,這裏關於該文件我就再也不贅述了,只是有一個小提示,若是你想簡單的解析一個JSON文本,那麼可使用eval()函數,改函數是JavaScript的內置函數,例如解析在JSON.stringify的案例中生成的JSON文本,可使用:
var myE = eval('["e",{"pluribus":"unum"}]‘);
來得到對象myE。
在JavaScript中串行化爲JSON-使用prototype.js
若是你和我同樣,喜歡在本身的項目中使用開源的JavaScript框架,那麼你可能能夠省去使用json2.js文件了,這裏以protype.js爲例,該文件能夠在
「[url]http://www.prototypejs.org[/url]」>[url]http://www.prototypejs.org[/url]下載,因爲本文不是在講JavaScript框架,這裏我假設你對prototype.js的使用已經有所瞭解了。
prototype.js中提供了對Object對象的toJSON方法,你可使用Object.toJSON()方法來實現對對象的串行化,例如:
var cat=
{
name:"hellokitty",
height:"6 apples"
}
alert(Object.toJSON(cat));
//將彈出對話框,內容爲 {"name": "hellokitty", "height": "6 apples"}
另外,在prototype.js中還有另外的JSON支持,主要是在Ajax對象中對Ajax返回請求中JSON內容的解析。這裏暫時與咱們的內容無關,也再也不介紹了。
PHP與JSON
在上面咱們一塊兒瞭解了PHP進行對象串行化的方法以及在JavaScript中進行將對象串行化爲JSON的方法,你大體會質疑我爲何將兩者放在一塊兒,由於他們的語法實際是不徹底同樣的,然而,在PHP中,能夠對JSON文本進行反串行化,也能夠將PHP的對象串行化爲JSON而非PHP風格的文本。這主要是靠json_decode和json_encode兩個函數來完成的,須要特別說明的是,這兩個函數在PHP
5 >= 5.2.0中才被支持,若是你要編寫運行在PHP4環境下的程序,那麼這兩個函數是不可使用的。
json_decode函數
語法
mixed json_decode ( string $json [, bool $assoc] )
獲取一個JSON編碼文本,而且將其轉換爲PHP變量
參數
json
被JSON編碼的文本
assoc
當爲TRUE時,返回的值爲聯合數組
返回值
返回一個對象,或者若是可選的assoc參數爲TRUE,則一個聯合數組將會被返回
json_encode函數
語法
string json_encode ( mixed $value )
該函數返回一個值的JSON表達式
參數
value
要被編碼的值,能夠爲除resource外的任何類型參數
這個函數僅在UTF-8編碼格式時起做用
返回值
當成功時返回編碼後的JSON文本
json_decode函數實例
下面兩個例子都基於咱們的一個情景假設,即,咱們有一個用戶註冊的模塊,這個模塊以」面向對象」的方式工做,在json_decode函數實例中,咱們在前臺將用戶的註冊信息變爲一個類的屬性,然後傳遞到後臺的php文件(這裏爲了簡便,就不用Ajax了)。在json_encode實例中,咱們在html文件中引用一個js文件,地址指向php文件,在php文件中輸出json編碼後的用戶對象(一樣爲了簡便,咱們直接生成一個對象而不從數據庫中取信息),並在html中輸出。
好了,先來看前臺的頁面json_encode.htm,這個頁面模仿了一般的註冊頁面,在其上面有一個表單,當提交時,觸發JavaScript函數,生成一個用戶對象user,將表單內容設爲用戶對象的屬性,生成JSON文本,以POST方式傳遞到後臺的json_encode.php文件。在js_encode.php文件中,將JSON文本用json_decode函數解析爲PHP對象,並輸出。
好了,先來看json_encode.html文件,文件代碼以下:
……省略HTML頭部,如下代碼位於head標籤
function JSON_test(o)
{
var user = {
name:document.getElementById('txt_name').value,
email:document.getElementById('txt_email').value,
password:document.getElementById('txt_name').value
}
var json_string = JSON.stringify(user);
document.getElementById(’txt_json’).value=json_string;
alert(」點擊肯定後將提交表單」);
o.submit();
}
……如下代碼位於body標籤
<form id=」form1″ name=」form1″ method=」post」 action=」json_encode.php」
onsubmit=」JSON_test(this)」>
<label for=」txt_name」>姓名</label>
<p>
<input type=」text」 name=」txt_name」 id=」txt_name」 />
</p>
<label for=」txt_email」>郵箱</label>
<p>
<input type=」text」 name=」txt_email」 id=」txt_email」 />
</p>
<p>
<label for=」txt_password」>密碼</label>
</p>
<p>
<input type=」text」 name=」txt_password」 id=」txt_password」 />
</p>
<p>
<input type=」text」 name=」txt_json」 id=」txt_json」 />
<label for=」button」></label>
<input type=」submit」 name=」button」 id=」button」 value=」JSON」 />
</p>
</form>
當提交表單時,將觸發JavaScript函數JSON_text(),該函數首先創建一個JavaScript對象user,將其name、email和password屬性分別設爲對應表單的值,然後使用json2.js文件的JSON.stringify方法將其轉換爲JSON文本json_string,最後設定隱藏域(這裏爲了使你看的清楚,我把這個隱藏域以文本框形式顯示了)txt_json的值爲json_string,並提交表單。
下面到json_encode.php文件,以下:
$json_string = $_POST["txt_json"];
if(ini_get("magic_quotes_gpc")=="1")
{
$json_string=stripslashes($json_string);
}
$user = json_decode($json_string);
echo var_dump($user);
在這個文件中,首先獲得json_encode.html文件中POST表單域txt_json的值,放入變量$json_string中,然後判斷,若是當前PHP的設定爲magic_quotes_gpc=On,即傳入的雙引號等會被轉義,這樣json_decode函數沒法解析,所以咱們要將其反轉義化。然後,使用json_decode函數將JSON文本轉換爲對象,保存在$user變量中,最終用echo
var_dump($user);,將該對象dump輸出出來,最終結果是:
object(stdClass)#1 (3) {
["name"]=>
string(10) "hanguofeng"
["email"]=>
string(18) 「[email]example@domain.com[/email]」
["password"]=>
string(10) 「hanguofeng」
}
json_encode函數實例
在這個例子中,仍然是由兩部分構成的,即json_enode.html和json_encode.php。在json_decode.html文件中,基本與json_decode.html文件的表單相似,可是不一樣的是,此次咱們要從json_encode.php文件中得到相應用戶的JSON文本,先來看這個PHP文件吧:
Class user
{
public $name="";
public $email="";
public $password="";
};
$myUser = new user;
$myUser->name="hanguofeng";
$myUser->email="[email]example@domain.com[/email]";
$myUser->password="hanguofeng";
$json_string = json_encode($myUser);
var user = echo($json_string);
這個文件首先創建類user,然後得到一個user類的實例myUser,並設定其用戶名、郵箱和密碼,接下來使用json_encode函數將其轉換爲JSON文本,保存在變量$json_string中,最後輸出一段JavaScript代碼,以在JavaScript中創建全局變量user。
接下,咱們須要在json_encode.html文件中引入json_encode.php文件,並獲得user對象的各個屬性,在這個文件中,你須要注意兩點,第一是,咱們以這樣的代碼引入json_encode.php文件爲JavaScript文件:
<script src="json_encode.php" type="text/javascript"></script>
第二點則是:
咱們在文本框代碼後面加入JavaScript的代碼,對文本框的value屬性進行操做,分別設定其值爲user對象的相應值。
實踐出真知
背景說明
OK,各位親愛的朋友,在通過上面這麼多這麼多的零散的關於PHP的串行化和JavaScript的串行化—JSON的說明後,咱們來作一個完整的東西,在這裏面,咱們涉及了JavaScript中的對象操做、對象串行化,還涉及了當串行化的JSON文本傳輸到後臺的PHP時,PHP進行的相應處理。
這裏須要說明的是,爲了將內容聚焦於本文所闡述的領域,咱們將這個項目精簡了不少,在這裏講的並不徹底是實際生產環境下的作法,而是爲了突出串行化的應用,在具體的地方我會詳細說明,但願不影響你對總體的理解。
咱們要完成的小案例是一個在線記事本的程序,用戶能夠在前臺添加若干個Tab(即一般所說的選項卡),每一個Tab保存必定的文本內容,你也能夠將它看成一個動態的選項卡生成和管理的程序。
程序的運行界面以下圖:
在這裏,你能夠看到有若干個Tab,當點擊這些Tab時,下面將顯示Tab的內容,同時你能夠刪除Tab和新增Tab,在完成對Tab的編輯後,能夠點擊「保存」按鈕,將改動傳輸到後臺的PHP進行處理,並保存在服務器上。
前臺JavaScript部分
在前臺的notepat.html文件中,咱們要使用JavaScript完成大多數對Tab進行管理的任務,所以我構建了一個Tab管理的類,用來對其進行添加、刪除等操做,這個類以下所示:
tabManager類的各個屬性、方法含義以下:
_tabs:「私有屬性」(加引號的緣由是JavaScript中並無私有公有的概念,這裏只是從設計上來說),該屬性中存儲了當前的tab數組,任何對Tab的操做將最終存儲在這裏。
_lastIndex:「私有屬性」,代表最後添加的索引,用於對各個Tab進行惟一標識。
getTabs():返回當前的tab數組。
setTabs(tabs):設定當前的tab數組。
add(ptitle,pcontent):新增一個標題爲ptitle,內容爲pcontent的tab。
del(pid):刪除id爲pid的tab。
clean():「私有方法」,用於刪除某個tab後,對tab數組進行精簡壓縮。
getTab(pid):用於得到指定的單個tab,參數pid爲要得到的tab的id。
debug():預留的debug方法。
同時注意咱們的tab對象有三個屬性,分別爲id、name和content。
這樣,基礎類的架構咱們就講解完畢了,這裏因爲其詳細代碼與本文話題關聯不大,就再也不詳細列出和講解了,稍後可能會單獨發表文章來講這裏。
那麼,咱們還須要構建一些函數,做爲控制器,來溝通頁面上各個按鈕的點擊事件和以前創建的tabManager類,這些函數包括:
selTab(o):當點擊頁面某個Tab時,切換內容區域以顯示相應Tab的內容,傳入參數爲所點擊的鏈接對象。
newTab():當點擊「新建Tab」按鈕時,負責詢問用戶新增Tab的信息,並調用tabManager.add()方法將用戶輸入的Tab信息創建一個新的Tab對象。
delTab():刪除當前激活的Tab。
saveTab():將對Tab的全部更改提交到PHP中。
loadTab():加載Tab。
showTabContent(id):被selTab()函數調用以顯示指定id的Tab的內容到內容區域。
draw(tabs):根據傳入的tabs數組重繪Tab導航區域。
那麼,這裏我要重點強調的函數就有兩個,分別是saveTab()和loadTab()。
先來看saveTab()函數:此函數源代碼以下:
function saveTab()
{
document.getElementById(」json_string」).value = JSON.stringify(tabManager.getTabs());
document.getElementById(」frmMain」).submit();
}
呵呵,好像比較簡單啊,這個函數首先經過調用tabManager類的getTabs()方法,得到咱們所操做的Tabs數組,然後調用json2.js文件中的JSON.stringfy()方法將其串行化,獲得串行化的JSON文本後,將其賦給隱藏域json_string,並提交表單,這裏我採起了簡單的方法,其實你在這裏也能夠採用Ajax的方式,將JSON文本傳遞到PHP中。
另外則是函數loadTab(),其代碼以下:
function loadTab()
{
tabManager.setTabs(notes);
draw(tabManager.getTabs());
}
這裏須要說明的是,咱們在本文件的開頭,經過以下代碼:
<script type=」text/javascript」 src=」load.php」></script>
引入了一個通過後臺處理的(你能夠看到,擴展名爲PHP)JavaScript文件load.php,。在這個文件中,創建了一個tab對象的數組notes。所以,在loadTab函數中,咱們調用了tabManager類的setTabs方法,設定tabManager類的「私有屬性」_tabs的值爲notes數組,此時就完成了對Tab的加載。
後臺PHP部分
當用戶在網頁上點擊「保存」按鈕後,會觸發前面所講解的saveTab()函數,最終提交表單到save.php頁面,該頁面讀取用戶提交的JSON文本,並將其轉換爲PHP對象,進行後續處理,其代碼以下:
$json_string = $_POST["json_string"];
if(ini_get(」magic_quotes_gpc」)==」1″)
{
$json_string=stripslashes($json_string);
}
$notes = json_decode($json_string);
foreach ($notes as $note)
{
echo $note->title.」<br>」.$note->content.」<br>————————-<br>」;
}
$p = f open(」load.php」,」w+」);
f write($p,」var notes=」.json_encode($notes).」;」);
f close($p);
首先經過訪問全局集合$_POST來得到提交的json_string隱藏域的值,然後進行處理,若是PHP的配置magic_quotes_gpc爲On,則此時提交的文本中,引號會被轉義,若是不進行處理,那麼後面的json解碼操做會失敗,所以咱們調用函數stripslashes()將其反轉義。
接下來咱們使用json_decode()函數對提交的JSON文本進行解碼,返回的對象保存在$notes變量中,此時$notes變量爲一個數組,數組中每個元素即一個Tab對象,爲了清楚的看到這一點,咱們對$notes數組進行迭代,依次打印出數組中每個Tab對象的標題和內容,最後,咱們打開文件load.php,將使用json_encode進行JSON編碼後的$notes對象寫入此文件,以待notepad.html文件調用,這樣就完成了對對象的持久化存儲工做。
這裏仍然須要說明的是咱們精簡的部分:在實際的生產環境中,你極可能須要在迭代$notes數組時將每個Tab對象的信息寫入數據庫中,以方便其餘的部分調用,而在load.php文件中,你可能並非直接將JSON文本寫入此文件,而是從數據庫中讀取一個結果集,然後迭代結果集,來生成一個PHP的數組,並將PHP數組進行JSON編碼後,輸出。
好了,絮絮不休一大堆,簡單點用個圖來表示吧:
我還有話要說
各位親愛的~讀者朋友,咱們這篇「長」達一萬五千字的連載完成了,在本文中,我想你瞭解了關於對象串行化的一些基本概念以及串行化在PHP和JavaScript中的使用方法。串行化只是一種思路,他的妙用在於你熟悉了在各種語言中對對象的操做以後,JSON和XML各有特色,根據本身的狀況進行優選才是王道。歡迎你們在論壇或者博客中與我交流。