Обнаружение плохих json-данных в PHP json_decode ()?

Я пытаюсь обрабатывать плохие данные 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 или есть какой-то другой отличный способ обнаружить это?

Вот несколько вещей о 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"; } 

Вы также можете использовать 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; } 

Я просто сломал себе голову над синтаксической ошибкой 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)))); 

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

/ ** * * 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' ); } } 

Вот как Гузл управляет 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; }