php json encode 編碼 PHP項(xiàng)目中遇到中文亂碼怎么辦?有解決方法嗎?
2021-01-31
PHP項(xiàng)目中經(jīng)常遇到中文亂碼,這是一個(gè)令人討厭的問題。但是,當(dāng)需要將內(nèi)容輸出到網(wǎng)頁時(shí),我們遵循以下兩個(gè)原則,并且通常不會出現(xiàn)中文亂碼。
首先是添加html頭
第二點(diǎn)是確保文件的編碼與meta設(shè)置的編碼一致。換句話說,如果我們的第一個(gè)字符集設(shè)置為UTF-8,那么我們的文件編碼也應(yīng)該設(shè)置為UTF-8。兩者應(yīng)該保持一致。
當(dāng)然,以上是針對網(wǎng)頁的情況,但是現(xiàn)在隨著Ajax在Web應(yīng)用程序中所占的比例越來越高,json格式的數(shù)據(jù)在數(shù)據(jù)傳輸中的使用越來越廣泛。因此,當(dāng)您使用json_encode在PHP中將數(shù)據(jù)轉(zhuǎn)換為json時(shí),會遇到中文亂碼或中文編碼的問題。
例如,
$data = array('id'=>1,'name'=>'跡憶博客','parId'=>0);
echo json_encode($data);
以上代碼的輸出結(jié)果為
{"id":1,"name":"\u8ff9\u5fc6\u535a\u5ba2","parId":0}
讓我們看一下,該功能已對中文“集意博客”進(jìn)行了十六進(jìn)制轉(zhuǎn)碼。不能說這是一個(gè)錯(cuò)誤,因?yàn)槭M(jìn)制表示形式是正確的中文。得到此結(jié)果后php json encode 編碼,我們還可以通過前端的js獲得所需的結(jié)果。但是,以這種方式使用仍然很麻煩。當(dāng)然,情況會因PHP版本而異。
對于某些版本的PHP,結(jié)果將如下所示
{"id":1,"name":null,"parId":0}
中文無法正確解析。
沒有辦法,中國問題太麻煩了。誰使計(jì)算機(jī)不是中國人發(fā)明的?當(dāng)然,有解決方案。讓我們了解兩種解決方案。
一、由json_encode的第二個(gè)參數(shù)解決
為解決上述問題,可以通過json_encode函數(shù)本身直接解決PHP> =5.4.0的版本。那是第二個(gè)參數(shù)加上JSON_UNESCAPED_UNICODE。
$data = array('id'=>1,'name'=>'跡憶博客','parId'=>0);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
現(xiàn)在您可以獲得正確的結(jié)果
{"id":1,"name":"跡憶博客","parId":0}
正確獲得了結(jié)果。但是,PHP的版本不能更改為5.4及更高版本。如何處理5.4以下的版本?
二、通過url編碼解決中文問題
我們知道PHP中有兩個(gè)函數(shù):urlencode和urldecode。我們可以使用urlencode函數(shù)對中文進(jìn)行url編碼,這樣字符串中就不會再有中文了,也不會遇到中文編碼問題。
$str = “跡憶博客”;
echo urlencode($str);
對Jiyi博客進(jìn)行網(wǎng)址編碼,結(jié)果如下
%E8%BF%B9%E5%BF%86%E5%8D%9A%E5%AE%A2
因此,在使用urlencode編碼上述數(shù)組的名稱的值,然后將其轉(zhuǎn)換為json格式后,中文編碼的問題將不復(fù)存在。
我們現(xiàn)在得到的結(jié)果是名稱編碼后的json字符串
{"id":1,"name":"%E8%BF%B9%E5%BF%86%E5%8D%9A%E5%AE%A2","parId":0}
最后,通過urldecode對url編碼的字符串進(jìn)行解碼。當(dāng)然,urldecode解碼不需要我們找到相應(yīng)的編碼字符串進(jìn)行解碼。我們可以直接解碼整個(gè)字符串。 urldecode將自動檢測相應(yīng)的url編碼的字符串并將其解碼。
$data = array('id'=>1,'name'=>urlencode('跡憶博客'),'parId'=>0);
$res =urldecode(json_encode($data));
echo $res;
所以結(jié)果是正確的
{"id":1,"name":"跡憶博客","parId":0}
此方法沒有版本限制php json encode 編碼,但是效率肯定會比第一種方法慢。
第二種方法的包裝函數(shù)-通過url編碼解決中文問題
現(xiàn)在是問題所在。對于第二種方法,我們不能在數(shù)組中的每個(gè)中文前面添加urlencode函數(shù)!這也是不現(xiàn)實(shí)的。然后,我們可以通過自己封裝json_encode函數(shù)來解決此類問題。
代碼如下
function onmpw_json_encode($data){
if(is_object($data)) return false;
if(is_array($data)){
$data = deal_array($data);
}
return urldecode(json_encode($data));
}
function deal_array($data){
if (is_array($data)) {
foreach ($data as $key => $val) {
if (is_array($val)) {
//如果是多維數(shù)組,通過遞歸來處理多維數(shù)組
$data[$key] = deal_array($val);
} else {
//對值進(jìn)行url編碼
$data[$key] = urlencode($val);
}
}
} elseif (is_string($data)) {
$data = urlencode($data);
}
return $data;
}
下面我們來看一個(gè)使用示例
$data = array(
array('id'=>1,'name'=>'跡憶博客','parId'=>0),
array('id'=>2,'name'=>'學(xué)無止境','parId'=>1),
array('id'=>3,'name'=>'趣味雜談','parId'=>1),
array('id'=>4,'name'=>'編程語言','parId'=>2),
array('id'=>5,'name'=>'網(wǎng)絡(luò)','parId'=>2),
array('id'=>6,'name'=>'算法','parId'=>2),
array('id'=>7,'name'=>'操作系統(tǒng)','parId'=>2),
array('id'=>8,'name'=>'數(shù)據(jù)庫','parId'=>2),
array('id'=>9,'name'=>'WEB前端','parId'=>2),
array('id'=>10,'name'=>'讀書','parId'=>3),
array('id'=>11,'name'=>'觀點(diǎn)與感想','parId'=>3)
);
$data = onmpw_json_encode($data);
echo $data;
現(xiàn)在我們有了想要的結(jié)果
[{"id":"1","name":"跡憶博客","parId":"0"},{"id":"2","name":"學(xué)無止境","parId":"1"},{"id":"3","name":"趣味雜談","parId":"1"},{"id":"4","name":"編程語言","parId":"2"},{"id":"5","name":"網(wǎng)絡(luò)","parId":"2"},{"id":"6","name":"算法","parId":"2"},{"id":"7","name":"操作系統(tǒng)","parId":"2"},{"id":"8","name":"數(shù)據(jù)庫","parId":"2"},{"id":"9","name":"WEB前端","parId":"2"}, {"id":"10","name":"讀書","parId":"3"},{"id":"11","name":"觀點(diǎn)與感想","parId":"3"}]
中文編碼問題非常普遍,我們都需要根據(jù)實(shí)際情況進(jìn)行更多總結(jié)。您可以輕松解決將來的開發(fā)中的類似問題。
對于上面的自定義json_encode函數(shù),我將其封裝在一個(gè)公共類中。源代碼在github上,我將繼續(xù)將一些常用功能封裝到該公共類中。歡迎下載。希望這對大家有幫助。