国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

PHP串行化與JSON

瀏覽:82日期:2024-01-14 13:11:50

原文連接:http://hi.baidu.com/lostdays/blog/item/8d76c300ec4e3c15738b65fa.html

總目錄

What 、Why、How

What; Why; How

PHP串行化語法; PHP串行化實例; 在JavaScript中串行化為JSON—使用json2.js; 在JavaScript中串行化為JSON—使用prototype.js

PHP與JSON

json_decode函數; json_encode函數; json_decode函數實例; json_encode函數實例

實踐出真知

背景說明; 前臺JavaScript部分; 后臺PHP部分

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}';var animal2=eval('(' + animal_str + ')');

我們通過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 =array('type' => 'human','name' => 'hanguofeng','age'=> '20');OK,上面的一些介紹只是讓你大致看到串行化和JSON是什么樣的東西,你無須對這里的代碼過分糾結,我們在后面會詳細講解的,下面我們來談談為什么要使用串行化。

Why

串行化首先是作為數據傳輸的方便而出現的,正如本文開始我提出的問題,我在JavaScript中建立了一個對象,我現在想將這個對象保存到服務器端的數據庫中,應該如何做,這其實上是一個“我如何將一個對象從瀏覽器提交到服務器”的問題,在這個傳輸過程中,我們知道,實際上只能夠傳遞字符流,字符流是一維(扁平)的,然而很多對象卻是多維的,如果要傳遞的對象是一個字符串,那么很簡單,我們直接將其作為傳遞的內容就可以了,如果要傳遞的對象是一個數組或者其他的結構呢,我們就需要用字符流來描述他,就比如在電話里面,我問你的名字是什么,你會告訴我,你的名字是張三、李四,而我問你,你的長相如何呢,你就需要用文字向我描述了,我們進行數據傳遞的媒介往往和這條電話線路一樣,只能傳遞字符流,而我們描述對象的過程,實際上就是串行化的過程。

另外,串行化也可以用于對對象的持久化存儲,也許你曾經也和我一樣,想著在數據庫的某一個字段中存儲一個對象,現在我們可以非常簡單的做到這一點,并且,你的這個數據庫字段不需要設定為特殊格式,設定為 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文件,我們在這個文件中用如下語句來創建一個哈希數組:

代碼:<?php$animal =array('type' => 'human','name' => 'hanguofeng','age'=> '20');?>為了測試這個數組的值,你可以使用print_r()函數來輸出數組,輸出的結果如下:

代碼:Array([type] => human[name] => hanguofeng[age] => 20)那么我們將他來串行化一下,串行化的代碼如下:

代碼:<?php$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”,即哈希數組的第一個元素的鍵。后面的部分以此類推,我們不再贅述,你可以試試自己將各種對象串行化,看看串行化后的字符串是如何構建的。下面來看數組的反串行化,即將我們上面生成的串行化字符串恢復為數組,代碼如下:

代碼:<?php$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中):

代碼:<?phpclass A {var $one = 1;function show_one() { echo $this->one;}}?>我們在如下代碼中創建類的實例并對該實例進行串行化:

代碼:<?phpinclude('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類。大括號內即該實例的各個屬性的名稱和值。而后我們將其進行反串行化:

代碼:<?phpinclude('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的官方網站www.json.org提供了對JavaScript對象實現JSON串行化的代碼庫—json2.js,你可以從這里獲得它。

獲得完畢json2.js文件后,你可以打開這個文件,在文件的前部分包含了相當大量的注釋信息,如果你的英文足夠好,那么你可以省略我這一節,參考該文件的注釋就可以了,如果作為程序員,你已經看夠了大片的字母,想看看我的漢字+字母,那你可以向下繼續了。

簡單的翻譯下這個注釋:可參考http://www.JSON.org/js.html該文件創建了一個包含兩個方法的全局對象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為例,該文件可以在http://www.prototypejs.org下載,由于本文不是在講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文件,文件代碼如下:

代碼:<!DOCTYPE html PUBLIC '//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8' /><title>json_decode</title><script src='http://www.cgvv.com.cn/bcjs/json2.js' type='text/javascript'></script><script type='text/javascript'>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();}</script></head><body><form name='form1' method='post' action='json_encode.php' onsubmit='JSON_test(this)'> <label for='txt_name'>姓名</label> <p><input type='text' name='txt_name' /> </p> <label for='txt_email'>郵箱</label> <p><input type='text' name='txt_email' /> </p> <p><label for='txt_password'>密碼</label> </p> <p><input type='text' name='txt_password' /> </p> <p> <input type='text' name='txt_json' /><label for='button'></label><input type='submit' name='button' value='JSON' /> </p></form></body></html>當提交表單時,將觸發JavaScript函數JSON_text(),該函數首先建立一個JavaScript對象user,將其name、email 和password屬性分別設為對應表單的值,而后使用json2.js文件的JSON.stringify方法將其轉換為JSON文本 json_string,最后設定隱藏域(這里為了使你看的清楚,我把這個隱藏域以文本框形式顯示了)txt_json的值為json_string,并提交表單。下面到json_encode.php文件,如下:

代碼:<?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 protected]' ['password']=> string(10) 'hanguofeng'}json_encode函數實例

在這個例子中,仍然是由兩部分構成的,即json_enode.html和json_encode.php。在json_decode.html文件中,基本與 json_decode.html文件的表單類似,但是不同的是,這次我們要從json_encode.php文件中獲得相應用戶的JSON文本,先來看這個PHP文件吧:

代碼:<?phpClass user{public $name='';public $email='';public $password='';};$myUser = new user;$myUser->name='hanguofeng';$myUser->email='[email protected]';$myUser->password='hanguofeng';$json_string = json_encode($myUser);?>var user = <?php echo($json_string)?>;這個文件首先建立類user,而后獲得一個user類的實例myUser,并設定其用戶名、郵箱和密碼,接下來使用json_encode函數將其轉換為 JSON文本,保存在變量$json_string中,最后輸出一段JavaScript代碼,以在JavaScript中建立全局變量user。接下,我們需要在json_encode.html文件中引入json_encode.php文件,并得到user對象的各個屬性,如下:

代碼:<!DOCTYPE html PUBLIC '//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8' /><title>json_encode</title><script src='http://www.cgvv.com.cn/bcjs/json_encode.php' type='text/javascript'></script></head><body><form name='form1' method='post'> <label for='txt_name'>姓名</label> <p><input type='text' name='txt_name' /> </p> <label for='txt_email'>郵箱</label> <p><input type='text' name='txt_email' /> </p> <p><label for='txt_password'>密碼</label> </p> <p><input type='text' name='txt_password' /> </p></form><script type='text/javascript' >document.getElementById('txt_name').value=user.name;document.getElementById('txt_email').value=user.email;document.getElementById('txt_password').value=user.password;</script></body></html>在這個文件中,你需要注意兩點,第一是,我們以這樣的代碼引入json_encode.php文件為JavaScript文件:

代碼:<script src='http://www.cgvv.com.cn/bcjs/json_encode.php' type='text/javascript'></script>第二點則是:我們在文本框代碼后面加入JavaScript的代碼,對文本框的value屬性進行操作,分別設定其值為user對象的相應值。

標簽: PHP
主站蜘蛛池模板: 亚洲男人天堂 | 亚洲欧美成人综合 | 亚洲综合成人网 | 一色屋色费精品视频在线观看 | 成人久久免费视频 | 玖玖玖视频在线观看视频6 玖玖影院在线观看 | 巨大热杵在腿间进进出出视频 | 女初高中福利视频在线观看 | 久久精品一 | 在线看欧美日韩中文字幕 | 成人国产综合 | 天天精品在线 | 国产午夜在线观看视频播放 | 国产一级一片 | 国产日产欧美精品一区二区三区 | 黑人黄色毛片 | 美女图片131亚洲午夜 | 欧美日韩国产亚洲一区二区三区 | 成人免费在线视频 | 国产理论最新国产精品视频 | 国产三级在线观看a | 刺激免费视频 | 第四色成人网 | 夜间福利网站 | 国产欧美日韩在线 | 欧美成人第一页 | 精品视频在线观看 | 免费观看女人一摸全是水 | 中国老太性色xxxxxhd | 国产欧美一区二区三区视频在线观看 | 最新国产毛片 | 精品视频一区二区三区 | 99国产精品久久久久久久日本 | 波多野结衣一区在线 | 国产精品二区在线 | 狠狠色综合色综合网站久久 | 一级毛片美国 | 高清欧美性狂猛bbbbbbxxxx | 久久免费看视频 | 69成人做爰视频在线观看 | 欧美成人自拍 |