|
|
|
|
|
在jquery的使用中,json的數(shù)據(jù)往往是從后臺(tái)取出來(lái),然而,由服務(wù)器端生成的json數(shù)據(jù),在前端調(diào)用時(shí)有時(shí)會(huì)遇到一些問(wèn)題,而出現(xiàn)亂碼則屬于較為常見(jiàn)的現(xiàn)象。本文將通過(guò)實(shí)例與大家分享一下php生成json數(shù)據(jù)為亂碼的處理方法。
php生成json數(shù)據(jù)的例子,非常多,這里不再介紹,本文要介紹的是對(duì)于php生成json數(shù)據(jù)為亂碼的處理方法。
php生成json數(shù)據(jù)為亂碼的處理方法一
先看看下面這段由php生成的json字符串:
{"total":239,"list":[{"code":"001","name":"\u4e2d\u56fd","addr":"Address 11","col4":"col4 data"},{"code":"002","name":"Name 2","addr":"Address 12","col4":"col4 data"}]}
"\u4e2d\u56fd"就是一段亂碼,我們現(xiàn)在的目標(biāo)是把這段亂碼變成可讀字符串。
通過(guò)測(cè)試,可以采用這樣的方法解決問(wèn)題:在php生成json的程序中,在json_encode之前,把所有數(shù)組內(nèi)所有內(nèi)容都用urlencode()處理一下,然用json_encode()轉(zhuǎn)換成json字符串,最后再用urldecode()將編碼過(guò)的中文轉(zhuǎn)回來(lái)。
下面為兩個(gè)處理函數(shù),可以直接調(diào)用:
/**************************************************************
*
* 將數(shù)組轉(zhuǎn)換為JSON字符串(兼容中文)
* @param array $array 要轉(zhuǎn)換的數(shù)組
* @return string 轉(zhuǎn)換得到的json字符串
* @access public
*
*************************************************************/
function JSON($array) {
arrayRecursive($array, 'urlencode', true);
$json = json_encode($array);
return urldecode($json);
}
/**************************************************************
*
* 使用特定function對(duì)數(shù)組中所有元素做處理
* @param string &$array 要處理的字符串
* @param string $function 要執(zhí)行的函數(shù)
* @return boolean $apply_to_keys_also 是否也應(yīng)用到key上
* @access public
*
*************************************************************/
function arrayRecursive(&$array, $function, $apply_to_keys_also = false){
static $recursive_counter = 0;
if (++$recursive_counter > 1000) {
die('possible deep recursion attack');
}
foreach ($array as $key => $value) {
if (is_array($value)) {
arrayRecursive($array[$key], $function, $apply_to_keys_also);
} else {
$array[$key] = $function($value);
}
if ($apply_to_keys_also && is_string($key)) {
$new_key = $function($key);
if ($new_key != $key) {
$array[$new_key] = $array[$key];
unset($array[$key]);
}
}
}
$recursive_counter--;
}
echo JSON($jarr);
通過(guò)這樣處理后,"\u4e2d\u56fd"這段亂碼就會(huì)變成了"中國(guó)"的可讀字符了。
php實(shí)現(xiàn)的另外一種解決方法
該方法跟上面的方法類似,也是先urlencode (),再u(mài)rldecode()來(lái)處理。
參考如下實(shí)例
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<?php
//建立數(shù)據(jù)庫(kù)連接
//$con = mysql_connect ( "localhost", "name", "yourpwd" );
if (! $con) {
die ( 'Could not connect: ' . mysql_error () );
}
//選擇查詢的數(shù)據(jù)庫(kù)
mysql_select_db ( "china_city", $con );
//設(shè)置字符集為UTF-8
mysql_query ( "set names utf8" );
$query = "select * from provincial";
//執(zhí)行SQL語(yǔ)句
$result = mysql_query ( $query );
//循環(huán) 將查詢的數(shù)據(jù)存入數(shù)組
while ( $row = mysql_fetch_assoc ( $result ) ) {
$response [] = $row;
}
//使用Foreach遍歷數(shù)組 同時(shí)使用urlencode處理 含有中文的字段
foreach ( $response as $key => $value ) {
$newData[$key] = $value;
$newData [$key] ['Provincial'] = urlencode ( $value ['Provincial'] );
}
echo urldecode ( json_encode ( $newData ) );
mysql_close ( $con );
?>
在客戶端處理json亂碼的方法
有人認(rèn)為,json_encode()輸出的是標(biāo)準(zhǔn)的json對(duì)象,那個(gè)不叫亂碼。我覺(jué)得也有道理,處理這種編碼應(yīng)該可以在客戶端實(shí)現(xiàn),而不需要在服務(wù)器處理。
如下便是在客戶端的處理方法。
如果是ajax,直接
echo json_encode($response); //這里輸出的中文是亂碼
在客戶端,
$.post('url.php', {'data': 'mydata'}, function(data){
data = eval('(' + data +')');
alert(data[0].Provincial);
})
彈出的不會(huì)是亂碼的。如果覺(jué)得eval函數(shù)不安全,可以使用$.getJSON( );,如果選擇了jquery庫(kù)的話。
還有,使用這種方法要注意的一點(diǎn)是,如果數(shù)據(jù)源還有特殊符號(hào),比如",\\,客戶端使用eval解析會(huì)出現(xiàn)問(wèn)題。
相關(guān)意見(jiàn)
echo json_encode($var); 輸出的是標(biāo)準(zhǔn)的json字符串,中文本來(lái)就是被轉(zhuǎn)換過(guò)的,不是什么亂碼。
如果項(xiàng)目編碼不是utf8,直接使用json_encode轉(zhuǎn)換出來(lái)的中文會(huì)變成NULL的,urlencode后就不存在這個(gè)問(wèn)題了。
生成json字符串的時(shí)候只能使用utf-8。不過(guò)可以用下面這個(gè)函數(shù)先實(shí)現(xiàn)utf8數(shù)組轉(zhuǎn)碼然后在直接使用json_encode():
function output($arr = array()) { return eval('return ' . iconv('GB2312', 'UTF-8', var_export($arr, true)) . ';');}
如果客戶端是用js寫(xiě),確實(shí)沒(méi)什么必要在php服務(wù)器端處理字符串問(wèn)題。但是我最近在用java的intent鏈接一個(gè)php的url返回?cái)?shù)據(jù),一直是轉(zhuǎn)化后的編碼,java客戶端也沒(méi)找到解決辦法,這時(shí)在服務(wù)器端的處理方法就很管用。