У меня простая структура php с 3 вложенными массивами.
Я не использую отдельные объекты и сам строю массивы с двумя вложенными циклами.
Вот образец var_dump массива, который я хочу преобразовать в Json.
array (size=2)
'tram B' =>
array (size=2)
0 =>
array (size=3)
'name' => string 'Ile Verte' (length=9)
'distance' => int 298
'stationID' => int 762
1 =>
array (size=3)
'name' => string 'La Tronche Hôpital' (length=18)
'distance' => int 425
'stationID' => int 771
16 =>
array (size=4)
0 =>
array (size=3)
'name' => string 'Bastille' (length=8)
'distance' => int 531
'stationID' => int 397
1 =>
array (size=3)
'name' => string 'Xavier Jouvin' (length=13)
'distance' => int 589
'stationID' => int 438
В другом скрипте у меня аналогичная структура, и он json_encode
отлично работает. Поэтому я не понимаю, почему json_encode
здесь не работает.
Изменить: похоже, проблема с кодировкой. Когда mb_detect_encoding
возвращает ASCII, json_encode
работает, но когда он возвращает UTF8, он больше не работает.
Edit2: json_last_error()
возвращает, JSON_ERROR_UTF8
что означает: искаженные символы UTF-8, возможно, неправильно закодированные .
This function only works with UTF-8 encoded data.
что проблем с кодировкой быть не должно.utf8_encode()
своегоname
массива, прежде чем передавать строкуjson_encode()
.JSON_PARTIAL_OUTPUT_ON_ERROR
опцию, чтобы увидеть проблему (например, поле с UTF8 будет пустым).Ответы:
Хорошо после 2 часов копания (см. Правки)
Выяснил следующее:
mb_detect_encoding
возвращает, вероятно, ошибочный ответ, некоторые строки, вероятно, не были UTF-8utf8_encode()
на те строки решить мою проблему, но смотри примечание нижеВот рекурсивная функция, которая может принудительно преобразовать в UTF-8 все строки, содержащиеся в массиве:
Используйте это просто так:
Примечание: utf8_encode () кодирует строку ISO-8859-1 в UTF-8 в соответствии с документами, поэтому, если вы не уверены в кодировке ввода, iconv () или mb_convert_encoding () могут быть лучшими вариантами, как указано в комментариях и других решениях.
источник
} else {
на} else if (is_string ($d)) {
; в противном случае вы все измените на строки (напримерINT
, станет aSTRING
).Matthieu Riegler представил действительно хорошее решение, однако мне пришлось немного изменить его для обработки объектов:
Еще одно замечание: json_last_error () может быть полезен при отладке функций json_encode () / json_encode ().
источник
elseif
вместоelse if
? (т.е. без пробела).if(): elseif:
else if(is_int($d)||is_bool($d)) return $d;
перед последним else по следующим{"success":true, "message":"Ⲃⲟⲟ𝓵ⲉⲁⲛ ⲁⲛⲇ Ⲓⲛϯⲉ𝓰ⲉꞅ𝛓"}
else
наelse if(is_string ($d))
; в противном случае вы все измените на строки (напримерINT
, станет aSTRING
).Для меня ответом на эту проблему была установка
charset=utf8
в моем PDO-соединении.источник
$mysqli->set_charset("utf8");
после обработки своей базы данных.utf8mb4
в последних версиях MySQL.utf8
устарело.Адам Бубела также представил действительно хорошее решение, которое помогло мне решить мою проблему, и вот упрощенная функция:
источник
У меня точно такая же проблема на PHP 5.6. Я использую Open Server + Nginx в Windows 7. Все кодировки установлены на UTF-8. Теоретически, согласно официальной документации , флаг
должен решить это. К сожалению, это не мой случай. Я не знаю, почему. Все приведенные выше фрагменты не решают мою проблему, поэтому я нашел свою реализацию. Я считаю, что это могло кому-то помочь. По крайней мере, русские буквы проходят проверку.
источник
Этот принятый ответ работает. Но если вы получаете данные из MySQL (как я), есть более простой способ.
После открытия базы данных перед запросом вы можете установить набор символов с помощью mysqli следующим образом:
ИЛИ
ССЫЛКА: http://php.net/manual/en/mysqli.set-charset.php
источник
Я столкнулся с этой проблемой на сервере с более старой версией PHP (5.2). Я использовал флаг JSON_FORCE_OBJECT, и, по-видимому, он не поддерживается до версии 5.3.
Поэтому, если вы используете этот флаг, обязательно проверьте свою версию!
Обходной путь, кажется, просто приведен к объекту перед кодированием, например:
источник
Возврат
mb_detect_encoding
может быть неверным:В зависимости от порядка обнаружения по умолчанию, приведенное выше может возвращать разные результаты, поэтому кодировка ошибочно отображается как UTF-8. ( Вот более крупный пример .)
Вероятно, что ваши данные не закодированы как UTF-8, поэтому
json_encode
возвращаетсяfalse
. Вы должны посмотреть на преобразование ваших строк в UTF-8 перед кодированием JSON:источник
Я получал данные от ob_get_clean () и имел ту же проблему, но приведенные выше решения не работают для меня. В моем случае решение было таким, может, это кому-то поможет.
источник
использование utf8_encode () в этой строке решило мою проблему.
источник
Я улучшил ответ Адама Бубелы. Я просто ненавижу, когда блоки не закрываются {и}. Он чище, и вы не вносите ошибок, или, может быть, я использовал Perl в прошлом :)
источник
Если вы получаете эти данные из базы данных, используйте
mysqli_set_charset($connection, "utf8");
соединение при получении параметров из базы данных.источник
эта проблема возникает иногда - вы не передаете управление доступом к заголовку.
В моем случае, если мне было добавлено какое-либо эхо до json_encode. Он показывал результат, иначе появлялась пустая страница.
я добавил
и моя проблема решена.
источник