可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm trying handle bad json data when parsed through json_decode(). I'm using the following script:
if(!json_decode($_POST)) { echo "bad json data!"; exit; }
If $_POST equals:
'{ bar: "baz" }'
Then json_decode handles the error fine and spits out "bad json data!"; However, if I set $_POST to something like "invalid data", it gives me:
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!
Do I need to write a custom script to detect valid json data, or is there some other nifty way to detect this?
回答1:
Here are a couple of things about json_decode
:
- it returns the data, or
null
when there is an error - it can also return
null
when there is no error : when the JSON string contains null
- it raises a warning where there is a warning -- warning that you want to make disappear.
To solve the warning problem, a solution would be to use the @
operator (I don't often recommend using it, as it makes debuging a lot more harder... But here, there is not much of a choice) :
$_POST = array( 'bad data' ); $data = @json_decode($_POST);
You'd then have to test if $data
is null
-- and, to avoid the case in which json_decode
returns null
for null
in the JSON string, you could check json_last_error
, which (quoting) :
Returns the last error (if any) occurred by last JSON parsing.
Which means you'd have to use some code like the following :
if ($data === null && json_last_error() !== JSON_ERROR_NONE) { echo "incorrect data"; }
回答2:
You can also use json_last_error : http://php.net/manual/en/function.json-last-error.php
which as documentation says :
Returns the last error (if any) occurred during the last JSON encoding/decoding.
here is an example
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; }
回答3:
This is how Guzzle handles 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; }
回答4:
I just broke my head over a json syntax error in what appeared to be perfect json: {"test1":"car", "test2":"auto"} from a url encoded string.
But in my case some of the above was html encoded, as adding html_entity_decode($string)
did the trick.
$ft = json_decode(html_entity_decode(urldecode(filter_input(INPUT_GET, 'ft', FILTER_SANITIZE_STRING))));
Hopefully this will save someone else some time.
回答5:
/** * * 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' ); } }