當我們在結合php和javascript實作某些功能時,經常會用到json。json是js的一種資料格式,可以直接被js解析。而php無法直接讀取json資料,但是php提供了json_decode函數來對json資料進行轉化,進而可以被php腳本通路。同時,php也提供了json_encode函數來将資料轉化成json格式。那麼,js中的原生json與php中通過json_encode函數轉化後的json是否完全一樣呢?今天,站長就和大家一起來探讨這個問題。
我們通過php向javascript傳遞數組資料時,通常要将其轉化為json格式,一遍javascript來擷取,那麼我們就以數組為例,先來看一下兩者之間的差別。
1、一維數組
$array=array("1","2","3");
使用json_encode函數轉化後,對應的json字元串為
["1","2","3"]。
細心的朋友很快就發現,轉化後得到的json字元串,就是javascript中的數組形式,那麼是否可以用js的數組通路方式來通路呢?
當然是可以的,但是你将這個json字元串傳遞給給js時,需要使用urlencode函數對其編碼,如:
<a href="javascript:show('<?php echo urlencode(json_encode(array('1','2','3')));?>')" id="aj">通路json</a>
我們可以用下面的js代碼來驗證:
function show(str){
var jobj=eval_r(decodeURI(str));
alert(jobj[2]);
}
大家自己試一試就會發現,是的,可以用js中通路一維數組的方式來通路它。eval方法将json字元串解釋為json對象,因為傳遞過來的是字元串,不轉化的話,你得到将是字元串中第三個字元的值。
我們再來對這個一維數組做一下變化,我們發現上面的一維數組沒有指定索引,是以它預設為數字索引,現在我們來給它加上鍵名:
$array=array('a'=>'1','b'=>'2','c'=>'3');
使用json_encode函數轉化後,對應的json字元串為
{"a":"1","b":"2","c":"3"}
。
我們很快就發現了其中的不同,最明顯的就是字元串兩端的[]變成了{},那麼這個字元串是否也可以按上面那樣處理後被js通路呢?我們不防試一試:
<a href="javascript:show('<?php echo urlencode(json_encode(array('a'=>'1','b'=>'2','c'=>'3')));?>')" id="aj">通路json</a>
function show(str){
var jobj=eval_r(decodeURI(str));
alert(jobj.a);
}
大家如果動手試了就知道,點選連結後,沒有出現彈窗。為什麼呢?是PHP生成的json字元串格式不對嗎?不是的,這是我們在使用eval函數解釋的時候,出錯了。把上面的函數代碼換成:
function show(str){
var jobj=eval_r('('+decodeURI(str)+')');
alert(jobj.a);
}
再試試吧!怎麼樣,可以通路了吧。這告訴我們,在使用eval方法處理帶有鍵名的json字元串時,需要在字元串兩端加速括号。至于為什麼,站長也不知道,站在巨人的肩膀上而已。
{"a":"1","b":"2","c":"3"}被傳遞給js後無法被直接解釋為json格式,但是如果你在js中使用該字元串直接建立json資料,是可以的。試試下面的代碼吧:
var jobj={"a":"1","b":"2","c":"3"};
alert(jobj.b);
2、二維數組
二維數組在PHP用的應用非常廣泛,是以了解二維數組轉化後的json格式非常重要。有了上面的例子做鋪墊,下面站長就直接給出示例代碼:
<a href="javascript:show('<?php echo urlencode(json_encode(array(array('1','2','3'))));?>')" id="aj">通路json</a>
function show(str){
var jobj=eval_r(decodeURI(str));
alert(jobj[0][0]);
}
大家運作,會發現,這跟一維數組差不多,這是不帶鍵名的例子,是以在show函數中,去掉字元串兩端的括号也是可以的。
下面,我們對二維數組進行一下變化,在第二維中加入鍵名,請看示例代碼:
<a href="javascript:show('<?php echo urlencode(json_encode(array(array("a"=>'1',"b"=>'2','3'))));?>')" id="aj">通路json</a>
function show(str){
var jobj=eval_r('('+decodeURI(str)+')');
alert(jobj[0].a);
}
alert(jobj[0][0]);
而這裡我們用的是
alert(jobj[0].a);不要問我為什麼,就是這樣。這就是json的通路方式。
上面的例子,我們對二維數組的第二維添加了鍵名,下面我們對第一維添加鍵名,看看通路方式又有什麼不同:
<a href="javascript:show('<?php echo urlencode(json_encode(array('k'=>array('1','2','3'))));?>')" id="aj">通路json</a>
function show(str){
var jobj=eval_r('('+decodeURI(str)+')');
alert(jobj.k[1]);
}
jobj.k[1]這樣的方式,大家一定已經發現了,隻要數組中含有鍵名,當數組被轉化為json格式後,就要使用json對象.鍵名這樣的方式來通路該鍵下的元素,上面的例子中,k鍵下的數組元素是數字索引,是以在json中使用k[1]這樣的方式來通路。
下面,我們對數組的第一維和第二維都添加鍵名:
<a href="javascript:show('<?php echo urlencode(json_encode(array('k'=>array("a"=>'1','2','3'))));?>')" id="aj">通路json</a>
function show(str){
var jobj=eval_r('('+decodeURI(str)+')');
alert(jobj.k.a);
}
json對象.鍵名
的方式來通路,如果有多個鍵就要用
json對象.鍵名.鍵名...
,不要問我為什麼,這就是json的通路方式,隻有javascript的發明者能向你解釋,他為什麼要這樣規定。
結論:
()
将json字元串括起來。
json對象.鍵名.鍵名...
的方式來通路,如果是數字索引則用
json對象[1]
或者
json對象.鍵名[1]
這樣的方式。