Detect Bad Json Data in PHP Json_Decode()

Detect bad json data in PHP json_decode()?

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

How handling error of JSON decode by try and catch

Another way to handle json decode error:-

if ($jsonObj === null && json_last_error() !== JSON_ERROR_NONE) {
echo "json data is incorrect";
}

Find line with error in php json_decode

Php doesn't have a function to validate json and find the error :(. Fortuanly there is a website (https://jsonformatter.curiousconcept.com/) that can do that.

Ps: make sure that you have checkt the validate checkbox :)

  • Marnix

PHP json_decode() returns NULL with valid JSON?

It could be the encoding of the special characters. You could ask json_last_error() to get definite information.

Update: The issue is solved, look at the "Solution" paragraph in the question.

PHP reading invalid json with json_decode();

With preg_replace you can do:

json_decode(preg_replace('#(?<pre>\{|\[|,)\s*(?<key>(?:\w|_)+)\s*:#im', '$1"$2":', $in));

Since the above example won't work with real data (the battle plans seldom survive first contact with the enemy) heres my second take:

$infile = 'http://www.google.com/finance/company_news?q=aapl&output=json&start=1&num=1';

// first, get rid of the \x26 and other encoded bytes.
$in = preg_replace_callback('/\\\x([0-9A-F]{2})/i',
function($match){
return chr(intval($match[1], 16));
}, file_get_contents($infile));

$out = $in;

// find key candidates
preg_match_all('#(?<=\{|\[|,)\s*(?<key>(?:\w|_)+?)\s*:#im', $in, $m, PREG_OFFSET_CAPTURE);

$replaces_so_far = 0;
// check each candidate if its in a quoted string or not
foreach ($m['key'] as $match) {
$position = $match[1] + ($replaces_so_far * 2); // every time you expand one key, offsets need to be shifted with 2 (for the two " chars)
$key = $match[0];
$quotes_before = preg_match_all('/(?<!\\\)"/', substr($out, 0, $position), $m2);
if ($quotes_before % 2) { // not even number of not-escaped quotes, we are in quotes, ignore candidate
continue;
}
$out = substr_replace($out, '"'.$key.'"', $position, strlen($key));
++$replaces_so_far;
}

var_export(json_decode($out, true));

But since google offers this data in RSS feed, i would recommend you to use that one if it works for your usecase, this is just for fun (-:

getting Invalid json error when I am decoding below data using json_decode in PHP

You need to use stripslashes to remove \\ and then decode

$data = '[{\\"field_display_txt\\":\\"New custom field phone\\",\\"field_value\\":0},{\\"field_display_txt\\":\\"New custom field\\",\\"field_value\\":\\"test_zapier\\"},{\\"field_display_txt\\":\\"New custom field select\\",\\"field_value\\":\\"1\\"}]';
$json = json_decode(stripslashes($data), true);

print_r($json);

http://sandbox.onlinephpfunctions.com/code/a43301dddeb89aedca6a50eed703f935ac721496

Why is PHP json_decode on JSON loaded from a database not working?

So, if i understand the problem correctly, you encode the data (becomes a string) and store it. Then you retrieve the string and decodes it. It becomes a string again?

  • When you say "echo" it, are you actually using echo? (because if you are expecting it to become object or array, you actually shouldn't use echo)
  • Are you storing it as UTF-8 in the database? - the JSON accepted by json_decode must be UTF8

Most likely, you should look into the string escaping on insert and retrieval. See https://www.php.net/manual/en/pdo.quote.php

(always prepare statements: https://www.php.net/manual/en/pdo.prepare.php)

How to json_decode invalid JSON with apostrophe instead of quotation mark

Here's an alternative solution to this problem:

function fixJSON($json) {
$regex = <<<'REGEX'
~
"[^"\\]*(?:\\.|[^"\\]*)*"
(*SKIP)(*F)
| '([^'\\]*(?:\\.|[^'\\]*)*)'
~x
REGEX;

return preg_replace_callback($regex, function($matches) {
return '"' . preg_replace('~\\\\.(*SKIP)(*F)|"~', '\\"', $matches[1]) . '"';
}, $json);
}

This approach is more robust than h2ooooooo's function in two respects:

  • It preserves double quotes occurring in a single quoted string, by applying additional escaping to them. h2o's variant will replace them with double quotes instead, thus changing the value of the string.
  • It will properly handle escaped double quotes \", for which h2o's version seems to go into an infinite loop.

Test:

$brokenJSON = <<<'JSON'
['foo', {"bar": "hel'lo", "foo": 'ba"r ba\"z', "baz": "wor\"ld ' test"}]
JSON;

$fixedJSON = fixJSON($brokenJSON);
$decoded = json_decode($fixedJSON);

var_dump($fixedJSON);
print_r($decoded);

Output:

string(74) "["foo", {"bar": "hel'lo", "foo": "ba\"r ba\"z", "baz": "wor\"ld ' test"}]"
Array
(
[0] => foo
[1] => stdClass Object
(
[bar] => hel'lo
[foo] => ba"r ba"z
[baz] => wor"ld ' test
)
)


Related Topics



Leave a reply



Submit