PHP json_decode () возвращает NULL с действительным JSON?

105

У меня есть этот объект JSON, хранящийся в текстовом файле:

{
    "MySQL": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "DatabaseName": "(dbname)"
    },
    "Ftp": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "RootFolder": "(rf)"
    },
    "BasePath": "../../bin/",
    "NotesAppPath": "notas",
    "SearchAppPath": "buscar",
    "BaseUrl": "http:\/\/montemaiztusitio.com.ar",
    "InitialExtensions": [
        "nem.mysqlhandler",
        "nem.string",
        "nem.colour",
        "nem.filesystem",
        "nem.rss",
        "nem.date",
        "nem.template",
        "nem.media",
        "nem.measuring",
        "nem.weather",
        "nem.currency"
    ],
    "MediaPath": "media",
    "MediaGalleriesTable": "journal_media_galleries",
    "MediaTable": "journal_media",
    "Journal": {
        "AllowedAdFileFormats": [
            "flv:1",
            "jpg:2",
            "gif:3",
            "png:4",
            "swf:5"
        ],
        "AdColumnId": "3",
        "RSSLinkFormat": "%DOMAIN%\/notas\/%YEAR%-%MONTH%-%DAY%\/%TITLE%/",
        "FrontendLayout": "Flat",
        "AdPath": "ad",
        "SiteTitle": "Monte Maíz: Tu Sitio",
        "GlobalSiteDescription": "Periódico local de Monte Maíz.",
        "MoreInfoAt": "Más información aquí, en el Periódico local de Monte Maíz.",
        "TemplatePath": "templates",
        "WeatherSource": "accuweather:SAM|AR|AR005|MONTE MAIZ",
        "WeatherMeasureType": "1",
        "CurrencySource": "cotizacion-monedas:Dolar|Euro|Real",
        "TimesSingular": "vez",
        "TimesPlural": "veces"
    }
}

Когда я пытаюсь его декодировать json_decode(), он возвращает NULL. Зачем? Файл доступен для чтения (я пробовал повторить эхо, file_get_contents()и он работал нормально).

Я тестировал JSON на http://jsonlint.com/, и это совершенно верно.

Что здесь не так?

Решение

В поисках ответов в Google я вернулся к SO: json_decode возвращает NULL после вызова веб-сервиса . В моем файле JSON была последовательность UTF BOM (некоторые двоичные символы, которых там не должно быть), что нарушало структуру JSON. Зашел в Hex Editor, стер байты. Все вернулось в норму. Почему это произошло? Потому что я редактировал файл с помощью Блокнота Microsoft Windows. Ужасная идея!

Джоэл А. Вильярреал Бертольди
источник
5
Работа с PHP 5.2.9; таким образом, я не могу использовать json_last_error().
Джоэл А. Вильярреал Бертольди
1
Также обратите внимание, что это может произойти с другими недопустимыми символами в середине файла. У меня только что json_decode () возвращал null, потому что строка содержала одно из этих специальных штрихов, вероятно, вставленных из MS Word, а затем, возможно, неправильно закодированных. Чтобы определить возможные проблемные символы, откройте файл JSON (я использовал в Notepad ++), измените кодировку (без преобразования) и сохраните как копию. Затем сравните два файла (я использовал WinMerge).
LinusR
(Проблема с Блокнотом Windows) Пожалуйста, проконсультируйтесь с этим, я тоже поделился проблемой, и она исправлена: stackoverflow.com/questions/10290849/…
Феликс Абалли
возможный дубликат json_decode возвращает NULL после вызова веб-службы
пользователь
Для меня это не было чем-то особенным, просто лишняя запятая в конце элемента объекта. Уберите: все, что делает ваш JSON несовместимым, вызовет ошибку. Бонусный совет: не доверяйте jsonviewer.stack.hu Используйте что-то вроде jsonlint
Аман Алам,

Ответы:

71

Это может быть кодировка специальных символов. Вы можете попросить json_last_error () получить определенную информацию.

Обновление: проблема решена, посмотрите пункт «Решение» в вопросе.

Пекка
источник
Я использую специальные символы с тех пор, как запустил приложение, и раньше никаких проблем не было. Локально декодирование JSON работает отлично. На моем сервере этого не происходит. И я не могу позвонить, json_last_error()потому что это PHP 5.2.9. Эта функция присутствует в PHP 5.3.0.
Джоэл А. Вильярреал Бертольди
1
Нет, это должно сработать. Я не могу проводить больше тестов прямо сейчас, если дойду до этого позже, я опубликую здесь. Также есть несколько подсказок в примечаниях, добавленных пользователем: de.php.net/json_decode, возможно, что-то помогает.
Pekka
1
Для меня на PHP 5.3 он отлично работает, когда текст закодирован в UTF-8. Но если я utf8_decode()сначала json_decode()пропущу текст , то молча терпит неудачу.
Мэтью,
1
@Pekka В поисках ответов в Google я вернулся к SO: stackoverflow.com/questions/689185/json-decode-returns-null-php . В моем файле JSON была последовательность UTF BOM (некоторые двоичные символы, которых там не должно быть), что нарушало структуру JSON. Зашел в Hex Editor, стер байты. Все вернулось в норму. Почему это произошло? Потому что я редактировал файл с помощью Блокнота Micro $ oft Windows. Ужасная идея!
Джоэл А. Вильярреал Бертольди
2
Об этом следует сообщить разработчикам PHP как об ошибке. Если спецификация была действительной UTF8, она не должна подавляться этим молча.
jmucchiello 09
87

Это сработало для меня

json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string), true );
Дунит Дханушка
источник
2
Я использовал это и получил массив, но мои языковые символы (ş, ç, ö, ..) также были удалены.
zkanoca
5
Это неверно, если данные json закодированы в UTF-8 (или, как я полагаю, в любой кодировке UTF). Он удалит действительные данные в кодировке UTF-8. Вероятно, это будет работать, если файл содержит только английский язык, но это всегда рискованное предположение. Я бы не стал этим пользоваться.
DaedalusAlpha
С этим он работает, но без него - нет, даже если две строки идентичны, я что-то упустил?
Руди Виссер
это действительно работает! но почему? в строке, которую я пытался расшифровать, не было никаких специальных символов
Тобиас Гассманн
Потрясающие. Работал у меня. :)
Sohil
32

Вы можете попробовать.

json_decode(stripslashes($_POST['data']))
Габриэль Кастильо Прада
источник
Я случайно позвонил stripslashes()дважды, в результате чего были удалены существенные косые черты и возникла недействительная строка JSON. Этот ответ помог мне обнаружить ошибку
Филипп,
22

Если вы проверите запрос в Chrome, вы увидите, что JSON - это текст, поэтому в JSON был добавлен пустой код.

Вы можете очистить его, используя

$k=preg_replace('/\s+/', '',$k);

Тогда вы можете использовать:

json_decode($k)

print_r затем покажет массив.

user2254008
источник
Спасибо за это - надеюсь, вы найдете недостающий английский.
Dean_Wilson
Человек, ты легенда, весь день боролся с этим.
Sboniso Marcus
Сделал это для меня !! Простая настройка, которую я сделал, - это добавление пробела в замену, я использую это, и, похоже, оно также заменяет мое пространство. теперь работает нормально. $k=preg_replace('/\s+/', ' ',$k);
Kash
Проблема в том, что это удаляет все пробелы, из-за чего английский текст слипается, не так ли?
CodeGuru
14

У меня была такая же проблема, и я решил ее, просто заменив символ кавычки перед декодированием.

$json = str_replace('"', '"', $json);
$object = json_decode($json);

Мое значение JSON было создано функцией JSON.stringify.

Япп Ка Хау
источник
В этом случае, возможно, использовалась функция htmlspecialchars, и JSON больше не может быть проанализирован. Чтобы отменить это, существует функция "htmlspecialchars_decode" вместо ручной замены & quot;
Дэви
12

Возможно, некоторые скрытые персонажи возятся с вашим json, попробуйте следующее:

$json = utf8_encode($yourString);
$data = json_decode($json);
Альберт Абдонор
источник
Попробовав все вышеперечисленные решения, это наконец сработало для меня. Благодаря тонну!!
Anis R.
7
$k=preg_replace('/\s+/', '',$k); 

сделал это для меня. И да, тестирование в Chrome. Спасибо пользователю2254008

Юрген Математика
источник
4

Просто подумал, что добавлю это, так как сегодня столкнулся с этой проблемой. Если строку JSON окружают какие-либо строковые отступы, json_decode вернет NULL.

Если вы извлекаете JSON из источника, отличного от переменной PHP, было бы разумно сначала «обрезать» его:

$jsonData = trim($jsonData);
Фил Ланаса
источник
4

это поможет вам понять, какой тип ошибки

<?php
// A valid json string
$json[] = '{"Organization": "PHP Documentation Team"}';

// An invalid json string which will cause an syntax 
// error, in this case we used ' instead of " for quotation
$json[] = "{'Organization': 'PHP Documentation Team'}";


foreach ($json as $string) {
    echo 'Decoding: ' . $string;
    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;
    }

    echo PHP_EOL;
}
?>
Энрико Темпести
источник
2

Просто сэкономьте один раз. Я потратил 3 часа, чтобы выяснить, что это просто проблема с кодировкой html. Попробуй это

if(get_magic_quotes_gpc()){
   $param = stripslashes($row['your column name']);
}else{
  $param = $row['your column name'];
}

$param = json_decode(html_entity_decode($param),true);
$json_errors = array(
JSON_ERROR_NONE => 'No error has occurred',
JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
JSON_ERROR_SYNTAX => 'Syntax error',
);
echo 'Last error : ', $json_errors[json_last_error()], PHP_EOL, PHP_EOL;
print_r($param);
Самуэль Кваме Антви
источник
1

Как заявил Юрген Мат, использование метода preg_replace, указанного пользователем2254008, также исправило его для меня.

Это не ограничивается Chrome, это, похоже, проблема преобразования набора символов (по крайней мере, в моем случае Unicode -> UTF8). Это устранило все проблемы, которые у меня были.

В качестве будущего узла объект JSON, который я декодировал, был получен из функции Python json.dumps. Это, в свою очередь, привело к появлению некоторых других антисанитарных данных, хотя с ними легко было справиться.

Дестрейф
источник
1

Если вы получаете json из базы данных, поместите

mysqli_set_charset($con, "utf8");

после определения ссылки соединения $ con

ТомоМиха
источник
Спасибо ТомоМиха. Это именно то, что подходит для всех моих проблем с MySQL, содержащим специальные символы, и при преобразовании с помощью json_decode это конкретное поле давало = null ....
KLL 05
1

Здесь вы можете найти небольшую оболочку JSON с корректирующими действиями, которые решают проблему спецификации и не-ASCI: https://stackoverflow.com/a/43694325/2254935

Кшиштоф Пшигода
источник
1

В моем случае это из-за одинарной кавычки в строке JSON.

Формат JSON допускает только двойные кавычки для ключей и строковых значений.

Пример:

$jsonString = '{\'hello\': \'PHP\'}'; // valid value should be '{"hello": "PHP"}'
$json = json_decode($jsonString);
print $json; // null

Я запутался из-за синтаксиса Javascript. В Javascript, конечно, можно сделать так:

let json = {
    hello: 'PHP' // no quote for key, single quote for string value
}

// OR:
json = {
    'hello': 'PHP' // single quote for key and value
}

но позже при преобразовании этих объектов в строку JSON:

JSON.stringify(json); // "{"hello":"PHP"}"
То
источник
0

Я решил эту проблему, распечатав JSON, а затем проверив источник страницы (CTRL / CMD + U):

print_r(file_get_contents($url));

Оказалось, что это был конечный <pre>тег.

Джеффри Розендал
источник
0

вы должны убедиться в этих точках

1. ваша строка json не содержит неизвестных символов

2. Строку json можно просматривать из онлайн-просмотра json (вы можете искать в Google как онлайн-просмотрщик или парсер для json), она должна просматриваться без каких-либо ошибок

3. ваша строка не имеет HTML-сущностей, она должна быть простым текстом / строкой

для объяснения пункта 3

$html_product_sizes_json=htmlentities($html);
    $ProductSizesArr = json_decode($html_product_sizes_json,true);

to (удалить функцию htmlentities ())

$html_product_sizes_json=$html;
    $ProductSizesArr = json_decode($html_product_sizes_json,true);
Хасан Саид
источник
0

Мне пришлось отключить error_reporting , чтобы json_decode () работал правильно. Звучит странно, но в моем случае это правда. Потому что между строкой JSON, которую я пытаюсь декодировать, напечатано какое-то примечание.

Shasi Kanth
источник
0

Самое важное, что нужно помнить, когда вы получаете результат NULL из данных JSON, который является допустимым, - это использовать следующую команду:

json_last_error_msg();

Т.е.

var_dump(json_last_error_msg());
string(53) "Control character error, possibly incorrectly encoded"

Затем вы исправляете это с помощью:

$new_json = preg_replace('/[[:cntrl:]]/', '', $json);
Грант
источник
0

Итак, у меня сработала html_entity_decode (). Пожалуйста, попробуйте это.

$input = file_get_contents("php://input");
$input = html_entity_decode($input);
$event_json = json_decode($input,true);
Суман Деол
источник
-5
<?php 
$json_url = "http://api.testmagazine.com/test.php?type=menu";
$json = file_get_contents($json_url);
$json=str_replace('},

]',"}

]",$json);
$data = json_decode($json);

echo "<pre>";
print_r($data);
echo "</pre>";
?>
user2648057
источник