Как в JSON декодирования поврежденных JSON с Апостроф вместо кавычек
Пример кода:
<?php
$json = "['foo', 'bar']";
var_dump( json_decode($json) );
он работает с PHP 5.5.3 , но не работает для более низких версий PHP
Он работает на моей машине с PHP 5.5.3, но он не работает везде.
Я знаю, что это неверный JSON, но мой веб-сервис дает мне JSON с символами ' вместе с "
['foo', "bar", {'test': "crazy "markup""}]
Как анализировать данные JSON с помощью Апостроф в PHP 5.3? Очевидно, что исходный JSON, который я хочу разобрать, более сложен.
(I не могу обновить свой PHP на рабочем сервере, ни получить правильный JSON от webservice)
7 ответов:
Вот альтернативное решение этой проблемы:
function fixJSON($json) { $regex = <<<'REGEX' ~ "[^"\\]*(?:\\.|[^"\\]*)*" (*SKIP)(*F) | '([^'\\]*(?:\\.|[^'\\]*)*)' ~x REGEX; return preg_replace_callback($regex, function($matches) { return '"' . preg_replace('~\\\\.(*SKIP)(*F)|"~', '\\"', $matches[1]) . '"'; }, $json); }Этот подход более надежен, чем функция h2ooooooo в двух отношениях:
- он сохраняет двойные кавычки, встречающиеся в одной строке с кавычками, применяя к ним дополнительное экранирование. вариант h2o заменит их двойными кавычками, тем самым изменив значение строки.
- он будет правильно обрабатывать экранированные двойные кавычки
\", для которых версия h2o, похоже, переходит в бесконечную петля.Тест:
$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);Вывод:
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 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 ) ); ?>Вывод :
string(41) "["foo", {"bar": "hel'lo", "foo": "ba'r"}]" Array ( [0] => foo [1] => stdClass Object ( [bar] => hel'lo [foo] => ba'r ) )Демо-версия
Одним из решений было бы построить прокси с использованием NodeJS. NodeJS прекрасно справится с неисправным JSON и вернет чистую версию:
johan:~ # node > JSON.stringify(['foo', 'bar']); '["foo","bar"]'Может быть, написать простой скрипт узла, который принимает данные JSON как STDIN и возвращает проверенный JSON в STDOUT. Таким образом, вы можете вызвать его из PHP.
Недостатком является то, что ваш сервер будет нуждаться в NodeJS. Не уверен, что это проблема для вас.
Ответ NikiCs уже на месте. Ваши входные данные, похоже, генерируются вручную, поэтому вполне возможно, что в пределах
'одиночных строк в кавычках вы получите неквотируемые"двойные. Поэтому вместо простого поиска и замены рекомендуется использовать регулярное выражение утверждение.Но есть также несколько пользовательских данных JSON парсеры, которые поддерживают немного больше синтаксис JavaScript выражение. Вероятно, лучше всего говорить о JSOL , JavaScript Object Literals, в этом случае точка.
Груши Services_JSON
Services_JSON может декодировать:
- ключи объектов без кавычек
- и строки, заключенные в одинарные кавычки.
Никаких дополнительных опций не требуется, просто
= (new Services_JSON)->decode($jsol);Up_json_decode () в upgradephp
На самом деле это был запасной вариант для ранних версий PHP без расширения JSON. Он реимплиментирует PHPs
json_decode(). Но есть также версияupgrade.php.prefixed, которую вы используете здесь.
Он вводит дополнительный флагJSON_PARSE_JAVASCRIPT.up_json_decode($jsol, false, 512, JSON_PARSE_JAVASCRIPT);И я совсем забыл о том, чтобы написать это, но он также поддерживает строки в одинарных кавычках.
Например:{ num: 123, "key": "value", 'single': 'with \' and unquoted " dbls' }Расшифрует в:
Очевидно, что синтаксический анализатор в userland работает значительно медленнее, чем просто предварительная обработка искаженного JSON. Если вы не ожидаете от вашего веб-сервиса никаких дополнительных gotchas, вместо этого перейдите к конверсии котировок.stdClass Object ( [num] => 123 [key] => value [single] => with ' and unquoted " double quotes )
Если вы знаете, что PHP 5.5.+ разберет этот JSON изящно, я бы передал ответы веб-службы через прокси-скрипт на веб-сервере PHP5.5+, который очищает ответы для более низких версий-то есть просто
echo json_encode(json_decode($response)); это стабильный и надежный подход.Если вы сделаете URL-адрес веб-службы настраиваемым через значение config, он будет работать для более низких версий, обращаясь к прокси, в более высоких версиях, обращаясь непосредственно к веб-службе.
Вы можете использовать (и, вероятно, модифицировать/расширять) библиотеку, чтобы построить AST из предоставленного JSON и заменить одинарные кавычки двойными кавычками.
Https://github.com/Seldaek/jsonlint/blob/master/src/Seld/JsonLint/Lexer.php
Может быть хорошим началом.
Быстрым решением может быть
str_replace("'","\"",$string). Это зависит от многих вещей, но я думаю, что вы могли бы попробовать.
Comments