2013-06-20 21 views
19

我有一個很奇怪的問題。json_decode返回JSON_ERROR_SYNTAX,但在線格式化程序說JSON是好的

我有一個JSON web服務。

當我與本網站檢查http://www.freeformatter.com/json-formatter.html#ad-output

一切都OK。

但是,當我加載我JSON使用此代碼:

$data = file_get_contents('http://www.mywebservice'); 

if(!empty($data)) 
{ 

    $obj = json_decode($data); 

switch (json_last_error()) { 
    case JSON_ERROR_NONE: 
     echo ' - JSON_ERROR_NONE'; 
    break; 
    case JSON_ERROR_DEPTH: 
     echo ' - JSON_ERROR_DEPTH'; 
    break; 
    case JSON_ERROR_STATE_MISMATCH: 
     echo ' - JSON_ERROR_STATE_MISMATCH'; 
    break; 
    case JSON_ERROR_CTRL_CHAR: 
     echo ' - JSON_ERROR_CTRL_CHAR'; 
    break; 
    case JSON_ERROR_SYNTAX: 
     echo "\r\n\r\n - SYNTAX ERROR \r\n\r\n"; 
    break; 
    case JSON_ERROR_UTF8: 
     echo ' - JSON_ERROR_UTF8'; 
    break; 
    default: 
     echo ' - Unknown erro'; 
    break; 
} 

我得到了錯誤:語法錯誤

這是不是幫助完整的。

這是一場噩夢。

我看到用PHP 5.5,我可以使用此功能:http://php.net/manual/en/function.json-last-error-msg.php

(但我沒有成功安裝PHP 5.5着呢,林不知道這個功能會給我更多的細節)

+3

請顯示JSON。 –

+0

JSON請。我們需要你的JSON。 – vikingmaster

+0

也許你應該讓你的錯誤信息更加冗長?例如,包含帶有錯誤消息的JSON? –

回答

1

你沒有顯示你的JSON,但這聽起來像它可能是一個無效的UTF-8序列的參數,大多數在線驗證器不會捕獲它。 確保您的數據是UTF-8,並檢查是否有外來字符。 你不需要PHP5來查看你的錯誤,使用error_log()來記錄問題。

54

我面臨同樣的問題,實際上有一些隱藏的角色看不見,你需要刪除它。 這是一個全球性的代碼,對很多情況下工作:json_decode前

<?php 
$checkLogin = file_get_contents("http://yourwebsite.com/JsonData"); 

// This will remove unwanted characters. 
// Check http://www.php.net/chr for details 
for ($i = 0; $i <= 31; ++$i) { 
    $checkLogin = str_replace(chr($i), "", $checkLogin); 
} 
$checkLogin = str_replace(chr(127), "", $checkLogin); 

// This is the most common part 
// Some file begins with 'efbbbf' to mark the beginning of the file. (binary level) 
// here we detect it and we remove it, basically it's the first 3 characters 
if (0 === strpos(bin2hex($checkLogin), 'efbbbf')) { 
    $checkLogin = substr($checkLogin, 3); 
} 

$checkLogin = json_decode($checkLogin); 
print_r($checkLogin); 
?> 
+0

只有這個解決方案對我有幫助。謝謝 –

+1

親愛的主席先生,你不知道這對我有多大幫助。我到處尋找解決方案,我幾乎放棄了。主席先生,你是天賜之物。 – deepakgates

+0

仍然想知道爲什麼這不是7.0.x版核心PHP的一部分。 (面掌) –

16

我解決了這個問題,將的stripslashes字符串。

$data = stripslashes($data); 
$obj = json_decode($data); 
+1

請格式化您的代碼。謝謝。 –

+3

不應該是$ data = stripslashes($ data); – TarranJones

+0

這是唯一的解決方案幫助我 – Harsh

26

卸下BOM(字節順序標記)是經常時候,你需要的解決方案:

function removeBOM($data) { 
    if (0 === strpos(bin2hex($data), 'efbbbf')) { 
     return substr($data, 3); 
    } 
    return $data; 
} 

你不應該有一個BOM,但如果它的存在,它是無形的,所以你贏了看不到它!

看到W3C on BOM's in HTML

使用BOM Cleaner,如果你有很多的文件來修復。

+0

我從'記事本++>格式> UTF-8沒有BOM'通過'Notepad ++'將編碼從'UTF-8'更改爲'UTF-8無BOM' – deadfish

+0

幾乎失去了1小時在找到答案之前嘗試了一百萬件事......感謝堆! – dmmd

0

我有同樣的問題。對我而言,這是由echo "<br/><pre>"造成的。我試圖通過使用exit(json_encode(utf8ize($resp_array)));將json字符串傳遞給另一個php文件在文件開頭,我已經刪除了breakline tag ...所以這對我來說是錯誤的。刪除此斷線標記,我能夠解碼我的JSON字符串一個其他的PHP文件..

3

爲了把所有的東西放在一起,我準備了JSON包裝與解碼自動糾正行動。

abstract class Json 
{ 
    public static function getLastError($asString = FALSE) 
    { 
     $lastError = \json_last_error(); 

     if (!$asString) return $lastError; 

     // Define the errors. 
     $constants = \get_defined_constants(TRUE); 
     $errorStrings = array(); 

     foreach ($constants["json"] as $name => $value) 
      if (!strncmp($name, "JSON_ERROR_", 11)) 
       $errorStrings[$value] = $name; 

     return isset($errorStrings[$lastError]) ? $errorStrings[$lastError] : FALSE; 
    } 

    public static function getLastErrorMessage() 
    { 
     return \json_last_error_msg(); 
    } 

    public static function clean($jsonString) 
    { 
     if (!is_string($jsonString) || !$jsonString) return ''; 

     // Remove unsupported characters 
     // Check http://www.php.net/chr for details 
     for ($i = 0; $i <= 31; ++$i) 
      $jsonString = str_replace(chr($i), "", $jsonString); 

     $jsonString = str_replace(chr(127), "", $jsonString); 

     // Remove the BOM (Byte Order Mark) 
     // It's the most common that some file begins with 'efbbbf' to mark the beginning of the file. (binary level) 
     // Here we detect it and we remove it, basically it's the first 3 characters. 
     if (0 === strpos(bin2hex($jsonString), 'efbbbf')) $jsonString = substr($jsonString, 3); 

     return $jsonString; 
    } 

    public static function encode($value, $options = 0, $depth = 512) 
    { 
     return \json_encode($value, $options, $depth); 
    } 

    public static function decode($jsonString, $asArray = TRUE, $depth = 512, $options = JSON_BIGINT_AS_STRING) 
    { 
     if (!is_string($jsonString) || !$jsonString) return NULL; 

     $result = \json_decode($jsonString, $asArray, $depth, $options); 

     if ($result === NULL) 
      switch (self::getLastError()) 
      { 
       case JSON_ERROR_SYNTAX : 
        // Try to clean json string if syntax error occured 
        $jsonString = self::clean($jsonString); 
        $result = \json_decode($jsonString, $asArray, $depth, $options); 
        break; 

       default: 
        // Unsupported error 
      } 

     return $result; 
    } 
} 

用法示例:

$json_data = file_get_contents("test.json"); 
$array = Json::decode($json_data, TRUE); 
var_dump($array); 
echo "Last error (" , Json::getLastError() , "): ", Json::getLastError(TRUE), PHP_EOL; 
+0

我一直在用一整天包含JSON的奇怪編碼文件進行鬥爭,並且這個類終於給了我一個可用的PHP數組 - 謝謝! – Hill79

0

我有同樣的問題。對我而言,這是由echo "<br/><pre>"造成的。

我試圖JSON字符串傳遞到使用另一個PHP文件:

exit(json_encode(utf8ize($resp_array))); 

在我decleared斷線標記文件的開始......所以,這是錯誤的我。刪除此折線標籤,我可以[...]

+0

這不是問題中所描述的問題,但它是一種非常常見的問題類型,難以發現,因此提及時很好。 – Simba