PHP JSON_Decode Fails Without Quotes on Key

PHP json_decode failed when value contains single quote (')

In your code the single quote(') is skipped with slash () thus it is breaking the JSON format.

Try removing the slash and try. It should work.

You should check the code where you are generating this JSON.

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

PHP json_decode() returns NULL with seemingly valid JSON?

This error means that your JSON string is not valid JSON!

Enable throwing exceptions when an error happens and PHP will throw an exception with the reason for why it failed.

Use this:

$json = json_decode($string, null, 512, JSON_THROW_ON_ERROR);

How to fix badly formatted JSON in PHP?

As others have already pointed out, it's best if you tell your client for the problem with the JSON formatting. Ask them to send a bugreport to the original developer/company so they could fix it. If he/they can't fix it - then offer your solution. You simply need to addslashes the string before you json_encode it.

If for some reason you end up having to fix the formatting, here is a way that might work for you:

$data = '"contact1": "David "Dave" Letterman", "contact2": "Peter "Robert" Smith",{\'test\': \'working "something"\'}';
function replace($match){
$key = trim($match[1]);
$val = trim($match[2]);

if($val[0] == '"')
$val = '"'.addslashes(substr($val, 1, -1)).'"';
else if($val[0] == "'")
$val = "'".addslashes(substr($val, 1, -1))."'";

return $key.": ".$val;
}
$preg = preg_replace_callback("#([^{:]*):([^,}]*)#i",'replace',$data);
var_dump($preg);
// string '"contact1": "David \"Dave\" Letterman", "contact2": "Peter \"Robert\" Smith",{'test': 'working \"something\"'}' (length=110)

Keep in mind this may break if somebody messes with the json format again.

Convert Json Javascript format to PHP readable format

Here is my solution to your problem. Yeah it is regex but it works.

$text = preg_replace(["/\\\\'/", '/("(.*?)"|(\w+))(\s*:\s*(".*?"|.))/s'], ["'", '"$2$3"$4'], $text);
$text = json_decode($text);

$text - is the bad formatted json

For the last comment this should work:

$text = preg_replace(["/\\\\'/", '/("(.*?)"|(\w+))(\s*:\s*(".*?"|.))/s', '/((:\s*)(0\d+))/'], ["'", '"$2$3"$4', '$2"$3"'], $text);

json_decode returns false if a value has leading zeros

You seem to be stuck in the unfortunate position of supporting crappy users / client software.

Try this regular expression replacement. If the data payloads are large, you may need to tweak some pcre limits

$sanitisedJson = preg_replace('/(?<=:)\s*0+(?=[1-9])/', '', $payload);


Related Topics



Leave a reply



Submit