json_decode возвращает JSON_ERROR_SYNTAX, но онлайн-форматирование говорит, что JSON в порядке

У меня очень странная проблема.

У меня есть веб-сервис JSON.

Когда я проверю его с помощью этого веб-сайта http://www.freeformatter.com/json-formatter.html#ad-output

Все в порядке.

Но когда я загружаю свой 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; } 

У меня ошибка: SYNTAX ERROR

КОТОРЫЙ НЕ ПОМОЧЬ ПОЛНОСТЬЮ ВСЕ.

Это кошмар.

Я вижу, что с помощью PHP 5.5 я мог бы использовать эту функцию: http://php.net/manual/en/function.json-last-error-msg.php

(но мне еще не удалось установить PHP 5.5, и я не уверен, что эта функция даст мне больше деталей)

Я столкнулся с той же проблемой, на самом деле есть невидимые скрытые символы, и вам нужно их удалить. Вот глобальный код, который работает во многих случаях:

 <?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); ?> 

Удаление спецификации (байтовый заказ) часто – это необходимое вам решение:

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

У вас не должно быть спецификации, но если она есть, она невидима, поэтому вы ее не увидите!

см. W3C о спецификациях в HTML

используйте BOM Cleaner, если у вас есть много файлов для исправления.

Я решил эту проблему добавить stripslashes в строку, прежде чем json_decode.

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

Чтобы собрать все вещи здесь и там, я подготовил 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; 

Вы не показываете свой JSON, но это звучит так, как будто это может быть неправильная последовательность UTF-8 в аргументе, большинство онлайн-валидаторов не поймают ее. убедитесь, что ваши данные UTF-8, а также проверьте наличие у вас иностранных символов. Вам не нужно PHP5, чтобы увидеть вашу ошибку, используйте error_log () для регистрации проблем.

У меня была такая же проблема. Для меня это вызывало echo "<br/><pre>" . Я пытался передать строку json в другой php-файл, используя exit(json_encode(utf8ize($resp_array))); В начале файла я разделил тег разрыва строки … Так что это была ошибка для меня. Удалив этот тег разделительной линии , я смог декодировать мою строку json другим файлом php.

У меня была такая же проблема. Для меня это вызывало echo "<br/><pre>" .

Я пытался передать строку json в другой php-файл, используя:

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

В начале файла я упустил тег break line … Так что это была ошибка для меня. Удалив этот тег разделительной линии, я смог […]