json_decode轉換json數據為數組出現的問題!


  json_decode這個函數是json_encode的反函數,一般傳遞數據的時候為了壓縮數據,會將數組格式的數據轉換成json格式,用到的函數就是json_encode,然后接收到數據之后再用json_decode轉換回數組,這里本來應該不會出現什么問題, 但也有意外,這個意外應該可以說也是自己造成,bom頭導致的bug,其實准確來說也不算bug,但就是讓你的數據無法正確轉換回來;

  bom頭的產生應該是你的文件在windows下用記事本這些東西編輯過之后的后果,可能無意之間就給這個bug的產生帶來了隱患;但是就算出現這個問題也不用慌張, 凡是都有解決的辦法;

  json_decode($json)之后可能出現返回空,null等結果,這個時候一般都是json格式出問題, 可以用json_last_error()來檢查,json_last_error()函數的使用方式就是在json_decode之后添加這個函數, 函數會返回值,返回0說明格式沒錯, 我遇到的事返回4,說明格式錯誤,之前用json在線檢測工具檢測數據,顯示是正確的,這兩個居然矛盾,讓我大惑不解,不過如果知道bom頭這個概念立馬就應該反應過來, bom頭是看不見的, 所以轉換的時候前面多了三個字節,當然看不見, 在線檢測的時候復制這個數據沒有bom頭的三個字節,當然也就正確了, 所以立馬用$json=substr($json,3);這個函數,去掉頭部的三個字節, 轉換之后ok了;

  問題解決之后感概萬千, 因為這個問題我找了兩天,本來問題影藏的不深,只是代碼不是自己寫的, 其次本地環境與服務器環境不一致, 反正諸多原因,一直沒想到會是這個問題;最后一步一步排查,鎖定這個函數;感覺以后編輯文件一定不能圖方便, 一個小錯誤就直接用記事本大概編輯一下就行了, 很容易出現這個bom頭問題;而且自己還不知道;

這里貼出一段代碼, 可以去除網站所有文件的bom頭信息;

 1 <?php
 2 if (isset($_GET['dir'])){ //設置文件目錄
 3 $basedir=$_GET['dir'];
 4 }else{
 5 $basedir = '.';
 6 }
 7 $auto = 1;
 8 checkdir($basedir);
 9 function checkdir($basedir){
10 if ($dh = opendir($basedir)) {
11 while (($file = readdir($dh)) !== false) {
12 if ($file != '.' && $file != '..'){
13 if (!is_dir($basedir."/".$file)) {
14 echo "filename: $basedir/$file ".checkBOM("$basedir/$file")." <br>";
15 }else{
16 $dirname = $basedir."/".$file;
17 checkdir($dirname);
18 }
19 }
20 }
21 closedir($dh);
22 }
23 }
24 function checkBOM ($filename) {
25 global $auto;
26 $contents = file_get_contents($filename);
27 $charset[1] = substr($contents, 0, 1);
28 $charset[2] = substr($contents, 1, 1);
29 $charset[3] = substr($contents, 2, 1);
30 if (ord($charset[1]) == 239 && ord($charset[2]) == 187 && ord($charset[3]) == 191) {
31 if ($auto == 1) {
32 $rest = substr($contents, 3);
33 rewrite ($filename, $rest);
34 return ("<font color=red>BOM found, automatically removed._<a href=http://www.k686.com>http://www.k686.com</a></font>");
35 } else {
36 return ("<font color=red>BOM found.</font>");
37 }
38 }
39 else return ("BOM Not Found.");
40 }
41 function rewrite ($filename, $data) {
42 $filenum = fopen($filename, "w");
43 flock($filenum, LOCK_EX);
44 fwrite($filenum, $data);
45 fclose($filenum);
46 }

 

這段代碼也是網上找來的, 用了覺得還是蠻方便,不過不敢在服務器上用,以免造成位置的別的什么錯誤;

所以想到一個折中的辦法, 現在本地跑了一下,把出現bom的文件全都替換,然后服務器上的問題並沒有解決,然后又在轉換json的時候添加了一個判斷

if(preg_match('/^\xEF\xBB\xBF/',$json))
{
$json=substr($json,3);
}

 

這樣如果檢測得到bom頭信息去掉就好了;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM