Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to json_decode invalid JSON with apostrophe instead of quotation mark

Tags:

Sample code:

<?php  $json = "['foo', 'bar']";  var_dump( json_decode($json) ); 

It works with PHP 5.5.3 but it fails for lower PHP's versions

It works on my machine with PHP 5.5.3 but it fails everywhere else.

I know it is incorrect JSON but my webservice gives me JSON with ' symbols together with "

['foo', "bar", {'test': "crazy \"markup\""}] 

Sandbox

How to parse JSON data with apostrophes in PHP 5.3? Obviously original JSON I want to parse is more complex.

(I can't upgrade my PHP on production server neither get proper JSON from webservice)

like image 565
Peter Avatar asked Dec 03 '13 10:12

Peter


2 Answers

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         ) ) 
like image 60
NikiC Avatar answered Oct 26 '22 22:10

NikiC


Here's a simple parser that'll fix your quotes for you. If it encounters a ' quote which isn't in a double quote ", it'll assume that it's wrong and replace the double quotes inside of that quote, and turn the quote enclosured into double quotes:

Example:

<?php     function fixJSON($json) {         $newJSON = '';          $jsonLength = strlen($json);         for ($i = 0; $i < $jsonLength; $i++) {             if ($json[$i] == '"' || $json[$i] == "'") {                 $nextQuote = strpos($json, $json[$i], $i + 1);                 $quoteContent = substr($json, $i + 1, $nextQuote - $i - 1);                 $newJSON .= '"' . str_replace('"', "'", $quoteContent) . '"';                 $i = $nextQuote;             } else {                 $newJSON .= $json[$i];             }         }          return $newJSON;     }      $brokenJSON = "['foo', {\"bar\": \"hel'lo\", \"foo\": 'ba\"r'}]";     $fixedJSON = fixJSON( $brokenJSON );      var_dump($fixedJSON);      print_r( json_decode( $fixedJSON ) ); ?> 

Output:

string(41) "["foo", {"bar": "hel'lo", "foo": "ba'r"}]" Array (     [0] => foo     [1] => stdClass Object         (             [bar] => hel'lo             [foo] => ba'r         )  ) 

DEMO

like image 44
h2ooooooo Avatar answered Oct 27 '22 00:10

h2ooooooo