Обнаружить плохие данные JSON в PHP json_decode ()? - PullRequest
40 голосов
/ 27 февраля 2010

Я пытаюсь обработать плохие данные JSON при анализе через json_decode (). Я использую следующий скрипт:

if(!json_decode($_POST)) {
  echo "bad json data!";
  exit;
}

Если $ _POST равно:

'{ bar: "baz" }'

Затем json_decode прекрасно обрабатывает ошибку и выдает «плохие данные json!»; Однако, если я установлю для $ _POST что-то вроде «неверных данных», это даст мне:

Warning: json_decode() expects parameter 1 to be string, array given in C:\server\www\myserver.dev\public_html\rivrUI\public_home\index.php  on line 6
bad json data!

Нужно ли мне писать собственный сценарий для определения допустимых данных json, или есть какой-нибудь другой изящный способ обнаружить это?

Ответы [ 6 ]

92 голосов
/ 27 февраля 2010

Вот пара вещей о json_decode:

  • возвращает данные или null при возникновении ошибки
  • также может возвращать null при отсутствии ошибки: когда строка JSON содержит null
  • выдает предупреждение, где есть предупреждение - предупреждение о том, что вы хотите, чтобы исчезнуть.


Чтобы решить проблему предупреждения, можно было бы использовать оператор @ (я не часто рекомендую его использовать, поскольку это делает отладку намного сложнее ... Но здесь, выбора не так много) :

$_POST = array(
    'bad data'
);
$data = @json_decode($_POST);

Затем вам нужно проверить, является ли $data null - и, чтобы избежать случая, когда json_decode возвращает null для null в строке JSON, вы можете проверить json_last_error, что (цитирование) :

Возвращает последнюю ошибку (если есть) произошел при последнем разборе JSON.


Это означает, что вам придется использовать некоторый код, подобный следующему:

if ($data === null
    && json_last_error() !== JSON_ERROR_NONE) {
    echo "incorrect data";
}
14 голосов
/ 30 июля 2013

Вы также можете использовать json_last_error: http://php.net/manual/en/function.json-last-error.php

который в документации говорит:

Возвращает последнюю ошибку (если есть), возникшую во время последнего JSON кодирование / декодирование.

вот пример

json_decode($string);

switch (json_last_error()) {
    case JSON_ERROR_NONE:
        echo ' - No errors';
    break;
    case JSON_ERROR_DEPTH:
        echo ' - Maximum stack depth exceeded';
    break;
    case JSON_ERROR_STATE_MISMATCH:
        echo ' - Underflow or the modes mismatch';
    break;
    case JSON_ERROR_CTRL_CHAR:
        echo ' - Unexpected control character found';
    break;
    case JSON_ERROR_SYNTAX:
        echo ' - Syntax error, malformed JSON';
    break;
    case JSON_ERROR_UTF8:
        echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
    break;
    default:
        echo ' - Unknown error';
    break;
}
5 голосов
/ 09 июня 2017

Вот как Guzzle обращается с JSON

    /**
 * Parse the JSON response body and return an array
 *
 * @return array|string|int|bool|float
 * @throws RuntimeException if the response body is not in JSON format
 */
public function json()
{
    $data = json_decode((string) $this->body, true);
    if (JSON_ERROR_NONE !== json_last_error()) {
        throw new RuntimeException('Unable to parse response body into JSON: ' . json_last_error());
    }

    return $data === null ? array() : $data;
}
2 голосов
/ 21 августа 2016

Я просто сломал голову из-за синтаксической ошибки json в том, что казалось идеальным json: {"test1":"car", "test2":"auto"} из строки, закодированной в URL.

Но в моем случае некоторые из вышеперечисленных кодировались в формате html, так как добавление html_entity_decode($string) помогло.

$ft = json_decode(html_entity_decode(urldecode(filter_input(INPUT_GET, 'ft', FILTER_SANITIZE_STRING))));

Надеюсь, это сэкономит кому-то еще время.

1 голос
/ 01 мая 2019

Начиная с PHP 7.3 , функция json_decode примет новую опцию JSON_THROW_ON_ERROR, которая позволит json_decode генерировать исключение вместо возврата нуля при ошибке.


Пример:

try {  
  json_decode("{", false, 512, JSON_THROW_ON_ERROR);  
}  
catch (\JsonException $exception) {  
  echo $exception->getMessage(); // displays "Syntax error"  
}
1 голос
/ 18 сентября 2016
/**
 * 
 * custom json_decode 
 * handle json_decode errors
 * 
 * @param type $json_text
 * @return type
 */
public static function custom_json_decode($json_text) {

    $decoded_array = json_decode($json_text, TRUE);
    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            return array(
                "status" => 0,
                "value" => $decoded_array
            );


        case JSON_ERROR_DEPTH:
            return array(
                "status" => 1,
                "value" => 'Maximum stack depth exceeded'
            );

        case JSON_ERROR_STATE_MISMATCH:
            return array(
                "status" => 1,
                "value" => 'Underflow or the modes mismatch'
            );

        case JSON_ERROR_CTRL_CHAR:
            return array(
                "status" => 1,
                "value" => 'Unexpected control character found'
            );

        case JSON_ERROR_SYNTAX:
            return array(
                "status" => 1,
                "value" => 'Syntax error, malformed JSON'
            );

        case JSON_ERROR_UTF8:
            return array(
                "status" => 1,
                "value" => 'Malformed UTF-8 characters, possibly incorrectly encoded'
            );

        default:
            return array(
                "status" => 1,
                "value" => 'Unknown error'
            );
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...