Подтвердить что ты не робот

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, и я не уверен, что эта функция даст мне больше деталей)

4b9b3361

Ответ 1

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

<?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 the first 3 characters 
if (0 === strpos(bin2hex($checkLogin), 'efbbbf')) {
   $checkLogin = substr($checkLogin, 3);
}

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

Ответ 2

Удаление BOM (Byte Order Mark) часто является решением, которое вам необходимо:

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

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

см W3C на спецификации в HTML

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

Ответ 3

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

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

Ответ 4

Чтобы собрать все вместе, я подготовил обертку JSON с расшифровкой автокорректирующих действий. Самую последнюю версию можно найти в моем GitHub Gist.

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

Ответ 5

Попробовав все решение без результата, это сработало для меня.

Надеюсь, это поможет кому-то

$data = str_replace('&quot;', '"', $data);

Ответ 6

У меня та же проблема, получение JSON_ERROR_CTRL_CHAR и JSON_ERROR_SYNTAX.
Это мое исправление.

$content = json_decode(json_encode($content), true);

Ответ 7

пожалуйста, сначала очистите данные JSON, а затем загрузите.

Ответ 8

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

Ответ 9

Строка JSON должна быть заключена в двойные кавычки, JSON недопустим, потому что вам не нужно экранировать символ '.

char = unescaped /
  escape (
      %x22 /          ; "    quotation mark  U+0022
      %x5C /          ; \    reverse solidus U+005C
      %x2F /          ; /    solidus         U+002F
      %x62 /          ; b    backspace       U+0008
      %x66 /          ; f    form feed       U+000C
      %x6E /          ; n    line feed       U+000A
      %x72 /          ; r    carriage return U+000D
      %x74 /          ; t    tab             U+0009
      %x75 4HEXDIG )  ; uXXXX                U+XXXX

' нет в списке.

Посмотрите этот список специальных символов, используемых в JSON:

\b  Backspace (ascii code 08)
\f  Form feed (ascii code 0C)
\n  New line
\r  Carriage return
\t  Tab
\"  Double quote
\\  Backslash character

Проверьте этот сайт для получения дополнительной документации.

Ответ 10

У меня были такие же проблемы. Я предпринял следующие шаги:

  1. изменил кодировку текста JSON

    $json = utf8_encode($json);
    
  2. Затем я просмотрел простой текст перед расшифровкой. Я нашел сумасшедшие символы, такие как

    ï

  3. тогда я просто снял его

    $json = str_replace(array('ï',''), '',$json);
    

    и я успешно расшифровал мой JSON

Ответ 11

Одна проблема, с моей стороны, состоит в том, что некоторые недействительные числа начинаются с 0, например: "001", "002", "003".

     "expectedToBeReturned":1,
     "inventoryNumber":001,
     "remindNote":"",

Замените 001 на 1, и это работает.

Ответ 12

Этот код работал для меня. В основном это удаляет скрытые символы.

    function cleanString($val)
    {
        $non_displayables = array(
        '/%0[0-8bcef]/',            # url encoded 00-08, 11, 12, 14, 15
        '/%1[0-9a-f]/',             # url encoded 16-31
        '/[\x00-\x08]/',            # 00-08
        '/\x0b/',                   # 11
        '/\x0c/',                   # 12
        '/[\x0e-\x1f]/',            # 14-31
        '/x7F/'                     # 127
        );
        foreach ($non_displayables as $regex)
        {
            $val = preg_replace($regex,'',$val);
        }
        $search  = array("\0","\r","\x1a","\t");
        return trim(str_replace($search,'',$val));
    }

Ответ 13

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

Ответ 14

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

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

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

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