Json error malformed utf 8 characters possibly incorrectly encoded 5 100

Решение типовых проблем с json_encode (PHP) Это краткая статья о наиболее вероятных проблемах с json_encode и их решениях. Иногда при кодировании данных в json, с помощью json_encode в php, мы получаем не тот результат который ожидаем. Я выделил три наиболее частые проблемы с которыми сталкиваются программисты: доступ к полям кодировка текстовых значений цифровые значения […]

Содержание

  1. Решение типовых проблем с json_encode (PHP)
  2. Доступ к полям
  3. Решение
  4. Почему не стоит использовать подход с toJson методом?
  5. Что если у меня очень много полей в класcе?
  6. А если нужно private-поля, из класса, который нет возможности редактировать?
  7. Кодировка текстовых значений
  8. Кириллица и другие знаки в UTF8
  9. Символы в других кодировках
  10. Цифровые значения
  11. Решение типовых проблем с json_encode (PHP)
  12. Доступ к полям
  13. Решение
  14. Почему не стоит использовать подход с toJson методом?
  15. Что если у меня очень много полей в класcе?
  16. А если нужно private поля с класса который нет возможности редактировать?
  17. Кодировка текстовых значений
  18. Кириллица и другие знаки в UTF8
  19. Символы в других кодировках
  20. Цифровые значения
  21. json_last_error
  22. Description
  23. Parameters
  24. Return Values
  25. Examples
  26. See Also
  27. Json error malformed utf 8 characters possibly incorrectly encoded 5 100

Решение типовых проблем с json_encode (PHP)

Это краткая статья о наиболее вероятных проблемах с json_encode и их решениях. Иногда при кодировании данных в json, с помощью json_encode в php, мы получаем не тот результат который ожидаем. Я выделил три наиболее частые проблемы с которыми сталкиваются программисты:

  • доступ к полям
  • кодировка текстовых значений
  • цифровые значения

Доступ к полям

Проблема заключается в том что json_encode имеет доступ только к публичным полям объекта. Например если у вас есть класс

то результатом выполнения следующего кода будет:

как видно в результирующий json были включены только публичные поля.
Что же делать если нужны все поля?

Решение

Для php = 5.4:
достаточно будет реализовать интерфейс JsonSerializable для нашего класса, что подразумевает добавление метода jsonSerialize который будет возвращать структуру представляющую объект для json_encode

Теперь мы можем использовать json_encode как и раньше

Почему не стоит использовать подход с toJson методом?

Многие наверно заметили что подход с созданием метода возвращающего json может быть использован и в версиях php >= 5.4. Так почему же не воспользоваться им? Все дело в том что ваш класс может быть использован как часть иной структуры данных

и результат уже будет совсем другой.
Также класс может использоваться другими программистами, для которых такой тип получение json-а с объекта может быть не совсем очевиден.

Что если у меня очень много полей в класcе?

В таком случае можно воспользоваться функцией get_object_vars

А если нужно private-поля, из класса, который нет возможности редактировать?

Может получиться ситуация когда нужно получить private поля (именно private, т.к. доступ к protected полям можно получить через наследование) в json-е. В таком случае необходимо будет воспользоваться рефлексией:

Кодировка текстовых значений

Кириллица и другие знаки в UTF8

Второй тип распространённых проблем с json_encode это проблемы с кодировкой. Часто текстовые значения которые нужно кодировать в json имеют в себе символы в UTF8 (в том числе кириллица) в результате эти символы будут представлены в виде кодов:

Отображение таких символов лечится очень просто — добавлением флага JSON_UNESCAPED_UNICODE вторым аргументом к функции json_encode:

Символы в других кодировках

Функция json_encode воспринимает строковые значения как строки в UTF8, что может вызвать ошибку, если кодировка другая. Рассмотрим маленький кусочек кода (данный пример кода максимально упрощен для демонстрации проблемной ситуации)

На первый взгляд ничего не предвещает проблем, да и что здесь может пойти не так? Я тоже так думал. В подавляющем большинстве случаев все будет работать, и по этой причине поиск проблемы занял у меня несколько больше времени, когда я впервые столкнулся с тем что результатом json_encode было false.

Для воссоздания такой ситуации предположим что p=%EF%F2%E8%F6%E0 (на пример: localhost?=%EF%F2%E8%F6%E0 ).
*Переменные в суперглобальных массивах $_GET и $_REQUEST уже декодированы.

Как можно увидеть из ошибки: проблема с кодировкой переданной строки (это не UTF8). Решение проблемы очевидное — привести значение в UTF8

Цифровые значения

Последняя типовая ошибка связана с кодированием числовых значений.

Как известно php не строго типизированный язык и позволяет использовать числа в виде строки, в большинстве случаев это не приводит к ошибкам внутри php приложения. Но так как json очень часто используется для передачи сообщений между приложениями, такой формат записи числа может вызвать проблемы в другом приложении. Желательно использовать флаг JSON_NUMERIC_CHECK:

Уже лучше. Но как видим «3.0» превратилось в 3, что в большинстве случаев будет интерпретировано как int. Используем еще один флаг JSON_PRESERVE_ZERO_FRACTION для корректного преобразования в float:

Прошу также обратить внимание на следующий фрагмент кода, что иллюстрирует ряд возможных проблем с json_encode и числовыми значениями:

Спасибо за прочтение.

Буду рад увидеть в комментариях описание проблем, с которыми вы сталкивались, что не были упомянуты в статье

Источник

Решение типовых проблем с json_encode (PHP)

Это краткая статья о наиболее вероятных проблемах с json_encode и их решениях. Иногда при кодировании данных в json, с помощью json_encode в php, мы получаем не тот результат который ожидаем. Я выделил три наиболее частые проблемы с которыми сталкиваются программисты:

  • доступ к полям
  • кодировка текстовых значений
  • цифровые значения

Доступ к полям

Проблема заключается в том что json_encode имеет доступ только к публичным полям объекта. Например если у вас есть класс

то результатом выполнения следующего кода будет:

как видно в результирующий json были включены только публичные поля.
Что же делать если нужны все поля?

Решение

Для php = 5.4:
достаточно будет реализовать интерфейс JsonSerializable для нашего класса, что подразумевает добавление метода jsonSerialize который будет возвращать структуру представляющую объект для json_encode

Теперь мы можем использовать json_encode как и раньше

Почему не стоит использовать подход с toJson методом?

Многие наверно заметили что подход с созданием метода возвращающего json может быть использован и в версиях php >= 5.4. Так почему же не воспользоваться им? Все дело в том что ваш класс может быть использован как часть иной структуры данных

и результат уже будет совсем другой.
Также класс может использоваться другими программистами, для которых такой тип получение json-а с объекта может быть не совсем очевиден.

Что если у меня очень много полей в класcе?

В таком случае можно воспользоваться функцией get_object_vars

А если нужно private поля с класса который нет возможности редактировать?

Может получиться ситуация когда нужно получить private поля (именно private, т.к. доступ к protected полям можно получить через наследование) в json-е. В таком случае необходимо будет воспользоваться рефлексией:

Кодировка текстовых значений

Кириллица и другие знаки в UTF8

Второй тип распространённых проблем с json_encode это проблемы с кодировкой. Часто текстовые значения которые нужно кодировать в json имеют в себе символы в UTF8 (в том числе кириллица) в результате эти символы будут представлены в виде кодов:

Отображение таких символов лечится очень просто — добавлением флага JSON_UNESCAPED_UNICODE вторым аргументом к функции json_encode:

Символы в других кодировках

Функция json_encode воспринимает строковые значения как строки в UTF8, что может вызвать ошибку, если кодировка другая. Рассмотрим маленький кусочек кода (данный пример кода максимально упрощен для демонстрации проблемной ситуации)

На первый взгляд ничего не предвещает проблем, да и что здесь может пойти не так? Я тоже так думал. В подавляющем большинстве случаев все будет работать, и по этой причине поиск проблемы занял у меня несколько больше времени, когда я впервые столкнулся с тем что результатом json_encode было false.

Для воссоздания такой ситуации предположим что p=%EF%F2%E8%F6%E0 (на пример: localhost?=%EF%F2%E8%F6%E0 ).
*Переменные в суперглобальных массивах $_GET и $_REQUEST уже декодированы.

Как можно увидеть из ошибки: проблема с кодировкой переданной строки (это не UTF8). Решение проблемы очевидное — привести значение в UTF8

Цифровые значения

Последняя типовая ошибка связана с кодированием числовых значений.

Как известно php не строго типизированный язык и позволяет использовать числа записаны в виде строки, в большинстве случаев это не приводит к ошибкам внутри php приложения. Но так как json очень часто используется для передачи сообщений между приложениями, такой формат записи числа может вызвать проблемы в другом приложении. Желательно использовать флаг JSON_NUMERIC_CHECK:

Уже лучше. Но как видим «3.0» превратилось в 3, что в большинстве случаев будет интерпретировано как int. Используем еще один флаг JSON_PRESERVE_ZERO_FRACTION для корректного преобразования в float:

Прошу так же обратить внимание на следующий фрагмент кода, что иллюстрирует ряд возможных проблем с json_encode и числовыми значениями:

Спасибо за прочтение.

Буду рад увидеть в комментариях описание проблем, с которыми вы сталкивались, что не были упомянуты в статье

Источник

json_last_error

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

json_last_error — Returns the last error occurred

Description

Returns the last error (if any) occurred during the last JSON encoding/decoding, which did not specify JSON_THROW_ON_ERROR .

Parameters

This function has no parameters.

Return Values

Returns an integer, the value can be one of the following constants:

JSON error codes

Constant Meaning Availability
JSON_ERROR_NONE No error has occurred
JSON_ERROR_DEPTH The maximum stack depth has been exceeded
JSON_ERROR_STATE_MISMATCH Invalid or malformed JSON
JSON_ERROR_CTRL_CHAR Control character error, possibly incorrectly encoded
JSON_ERROR_SYNTAX Syntax error
JSON_ERROR_UTF8 Malformed UTF-8 characters, possibly incorrectly encoded
JSON_ERROR_RECURSION One or more recursive references in the value to be encoded
JSON_ERROR_INF_OR_NAN One or more NAN or INF values in the value to be encoded
JSON_ERROR_UNSUPPORTED_TYPE A value of a type that cannot be encoded was given
JSON_ERROR_INVALID_PROPERTY_NAME A property name that cannot be encoded was given
JSON_ERROR_UTF16 Malformed UTF-16 characters, possibly incorrectly encoded

Examples

Example #1 json_last_error() example

// 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;
>

The above example will output:

Example #2 json_last_error() with json_encode()

// An invalid UTF8 sequence
$text = «xB1x31» ;

$json = json_encode ( $text );
$error = json_last_error ();

var_dump ( $json , $error === JSON_ERROR_UTF8 );
?>

The above example will output:

Example #3 json_last_error() and JSON_THROW_ON_ERROR

// An invalid UTF8 sequence which causes JSON_ERROR_UTF8
json_encode ( «xB1x31» );

// The following does not cause a JSON error
json_encode ( ‘okay’ , JSON_THROW_ON_ERROR );

// The global error state has not been changed by the former json_encode()
var_dump ( json_last_error () === JSON_ERROR_UTF8 );
?>

The above example will output:

See Also

  • json_last_error_msg() — Returns the error string of the last json_encode() or json_decode() call
  • json_decode() — Decodes a JSON string
  • json_encode() — Returns the JSON representation of a value

Источник

Json error malformed utf 8 characters possibly incorrectly encoded 5 100

Error encoding model [App\Models\Tenants\Employee] with ID [202] to JSON: Malformed UTF-8 characters, possibly incorrectly encodedn n

Here’s the situation; I’ve got a database with table full of employee data that includes a column ‘achternaam’ (lastname in Dutch), all of which are using utf8mb4_unicode_ci . We receive data from an external third party, parse it and put in our database. One of these employees we’ve imported has this surname: u00d6zyaprak — Tu00fczu00fcn. Yeah, that’s a lot of umlauts. n

Storing this in the database is no problem and the name is shown normally in Navicat. However, when I try try to parse that entity to JSON via a simple call of return response()->json(Employee::find(202)); I get the exception above. n

I’d love some ideas on what I or Laravel (e.g. via config) is doing wrong. n

JSON doesnt like non UTF-8 data. n

Try saving it as htmlentities before JSON encoding. n

n $test = array( ‘name’ => ‘u00d6zyaprak — Tu00fczu00fcn’ );n $test[‘bnamela’] = htmlentities( $test[‘name’] );nn echo json_encode( $test );n n

You can also try: n

return response()->json(Employee::find(202), 200, [], JSON_UNESCAPED_UNICODE); n n

I tried your first suggestion which worked. However, I’d now consider the data in my database to be faulty as the name would be stored as ‘u00d6zyaprak — Tu00fczu00fcn’. This would only cause more problems for the rest of the application. It doesn’t seem worth it to have to decode this everywhere I use it in the project (not just Blade/Vue). n

$employee = Employee::select(‘id’, ‘initialen’, ‘voornaam’, ‘achternaam’)->find(202);n$employee->achternaam = json_encode($employee->achternaam);nnreturn response()->json($employee);n n

Which gives us: n

Vue then shows this as n

«\u00d6zyaprak — T\u00fcz\u00fcn»n n

Could you try a couple more things for me please? Tinker would be great for rapidly testing this: n

public function getInitialsAttribute()n<n return substr($this->voornaam, 0, 1) . substr($this->achternaam, 0, 1);n>n n

This seemed to be the evil doer. The command you had me run in Tinker all show the following value for initials : n

=> [n «id» => 202,n «initialen» => «D.»,n «voornaam» => «Derya»,n «achternaam» => «u00d6zyaprak — Tu00fczu00fcn»,n «initials» => b»Du00c3″,n . n ]n n

b»Du00c3″ is not a very valid value =) I removed the attribute and everything worked. Now I just need to fix this little method but that’s a piece of cake. n

Could you try a couple more things for me please? Tinker would be great for rapidly testing this: n

Источник

Не открываются пользовательские группы после обновления (проблема с кодировкой)

 

Пользователь 4606427

Заглянувший

Сообщений: 3
Регистрация: 18.09.2020

#1

22.06.2022 21:45:46

После последних обновлений портала (коробка), не отображаются содержимое пользовательских групп.
Какие могут быть способы решения?

При открытии любой группы (даже созданную только что) получаю такое:

Часть лога /var/log/php/exceptions.log

Код
2022-06-22 21:04:11 - Host: <имя хоста>:443 - UNCAUGHT_EXCEPTION - [BitrixMainArgumentException] 
JSON error: Malformed UTF-8 characters, possibly incorrectly encoded [5] (100)
/home/bitrix/www/bitrix/modules/main/lib/web/json.php:160
#0: BitrixMainWebJson::throwException(string)
   /home/bitrix/www/bitrix/modules/main/lib/web/json.php:147
#1: BitrixMainWebJson::checkException(integer)
   /home/bitrix/www/bitrix/modules/main/lib/web/json.php:37
#2: BitrixMainWebJson::encode(array)
   /home/bitrix/www/bitrix/components/bitrix/main.interface.buttons/templates/.default/template.php:89
#3: include(string)
   /home/bitrix/www/bitrix/modules/main/classes/general/component_template.php:790
#4: CBitrixComponentTemplate->__IncludePHPTemplate(array, array, string)
   /home/bitrix/www/bitrix/modules/main/classes/general/component_template.php:885
#5: CBitrixComponentTemplate->IncludeTemplate(array)
   /home/bitrix/www/bitrix/modules/main/classes/general/component.php:775
#6: CBitrixComponent->showComponentTemplate()
   /home/bitrix/www/bitrix/modules/main/classes/general/component.php:716
#7: CBitrixComponent->includeComponentTemplate()
   /home/bitrix/www/bitrix/components/bitrix/main.interface.buttons/class.php:789
#8: CMainInterfaceButtons->executeComponent()
   /home/bitrix/www/bitrix/modules/main/classes/general/component.php:660
#9: CBitrixComponent->includeComponent(string, array, NULL, boolean)
   /home/bitrix/www/bitrix/modules/main/classes/general/main.php:1072
#10: CAllMain->IncludeComponent(string, string, array)
   /home/bitrix/www/bitrix/templates/bitrix24/components/bitrix/socialnetwork.group_menu/.default/template.php:451
#11: include(string)
   /home/bitrix/www/bitrix/modules/main/classes/general/component_template.php:790
#12: CBitrixComponentTemplate->__IncludePHPTemplate(array, array, string)
   /home/bitrix/www/bitrix/modules/main/classes/general/component_template.php:885
#13: CBitrixComponentTemplate->IncludeTemplate(array)
   /home/bitrix/www/bitrix/modules/main/classes/general/component.php:775
#14: CBitrixComponent->showComponentTemplate()
   /home/bitrix/www/bitrix/modules/main/classes/general/component.php:716
#15: CBitrixComponent->includeComponentTemplate()
   /home/bitrix/www/bitrix/components/bitrix/socialnetwork.group_menu/component.php:354
#16: include(string)
   /home/bitrix/www/bitrix/modules/main/classes/general/component.php:607
#17: CBitrixComponent->__includeComponent()
   /home/bitrix/www/bitrix/modules/main/classes/general/component.php:684
#18: CBitrixComponent->includeComponent(string, array, object, boolean)
   /home/bitrix/www/bitrix/modules/main/classes/general/main.php:1072
#19: CAllMain->IncludeComponent(string, string, array, object, array)
   /home/bitrix/www/bitrix/components/bitrix/socialnetwork_group/templates/.default/util_group_menu.php:52
#20: include(string)
   /home/bitrix/www/bitrix/components/bitrix/socialnetwork_group/templates/.default/group.php:99
#21: include(string)
   /home/bitrix/www/bitrix/modules/main/classes/general/component_template.php:790
#22: CBitrixComponentTemplate->__IncludePHPTemplate(array, array, string)
   /home/bitrix/www/bitrix/modules/main/classes/general/component_template.php:885
#23: CBitrixComponentTemplate->IncludeTemplate(array)
   /home/bitrix/www/bitrix/modules/main/classes/general/component.php:775
#24: CBitrixComponent->showComponentTemplate()
   /home/bitrix/www/bitrix/modules/main/classes/general/component.php:716
#25: CBitrixComponent->includeComponentTemplate(string, string)
   /home/bitrix/www/bitrix/components/bitrix/socialnetwork_group/component.php:1215
#26: include(string)
   /home/bitrix/www/bitrix/modules/main/classes/general/component.php:607
#27: CBitrixComponent->__includeComponent()
   /home/bitrix/www/bitrix/modules/main/classes/general/component.php:684
#28: CBitrixComponent->includeComponent(string, array, NULL, boolean)
   /home/bitrix/www/bitrix/modules/main/classes/general/main.php:1072
#29: CAllMain->IncludeComponent(string, string, array)
   /home/bitrix/www/workgroups/index.php:160
#30: include_once(string)
   /home/bitrix/www/bitrix/modules/main/include/urlrewrite.php:160
#31: include_once(string)
   /home/bitrix/www/bitrix/urlrewrite.php:2
----------
 

Пользователь 5224375

Заглянувший

Сообщений: 3
Регистрация: 29.04.2021

#2

23.06.2022 11:25:40

Та же самая проблема, перестали работать гриппы и проекты, причем если локализацию изменить на [ru] с [ua] все работает:

Код
2022-06-23 11:04:52 - Host: host.ru:443 - UNCAUGHT_EXCEPTION - [BitrixMainArgumentException]
JSON error: Malformed UTF-8 characters, possibly incorrectly encoded [5] (100)
/home/bitrix/www/bitrix/modules/main/lib/web/json.php:160
#0: BitrixMainWebJson::throwException(string)
        /home/bitrix/www/bitrix/modules/main/lib/web/json.php:147
#1: BitrixMainWebJson::checkException(integer)
        /home/bitrix/www/bitrix/modules/main/lib/web/json.php:37
#2: BitrixMainWebJson::encode(array)
        /home/bitrix/www/bitrix/components/bitrix/main.interface.buttons/templates/.default/template.php:89
#3: include(string)
        /home/bitrix/www/bitrix/modules/main/classes/general/component_template.php:790
#4: CBitrixComponentTemplate->__IncludePHPTemplate(array, array, string)
        /home/bitrix/www/bitrix/modules/main/classes/general/component_template.php:885
#5: CBitrixComponentTemplate->IncludeTemplate(array)
        /home/bitrix/www/bitrix/modules/main/classes/general/component.php:775
#6: CBitrixComponent->showComponentTemplate()
        /home/bitrix/www/bitrix/modules/main/classes/general/component.php:716
#7: CBitrixComponent->includeComponentTemplate()
        /home/bitrix/www/bitrix/components/bitrix/main.interface.buttons/class.php:789
#8: CMainInterfaceButtons->executeComponent()
        /home/bitrix/www/bitrix/modules/main/classes/general/component.php:660
#9: CBitrixComponent->includeComponent(string, array, NULL, boolean)
        /home/bitrix/www/bitrix/modules/main/classes/general/main.php:1072
#10: CAllMain->IncludeComponent(string, string, array)
        /home/bitrix/www/bitrix/templates/bitrix24/components/bitrix/socialnetwork.group_menu/.default/template.php:451
#11: include(string)
        /home/bitrix/www/bitrix/modules/main/classes/general/component_template.php:790
#12: CBitrixComponentTemplate->__IncludePHPTemplate(array, array, string)
        /home/bitrix/www/bitrix/modules/main/classes/general/component_template.php:885
#13: CBitrixComponentTemplate->IncludeTemplate(array)
        /home/bitrix/www/bitrix/modules/main/classes/general/component.php:775
#14: CBitrixComponent->showComponentTemplate()
        /home/bitrix/www/bitrix/modules/main/classes/general/component.php:716
#15: CBitrixComponent->includeComponentTemplate()
        /home/bitrix/www/bitrix/components/bitrix/socialnetwork.group_menu/component.php:354
#16: include(string)
        /home/bitrix/www/bitrix/modules/main/classes/general/component.php:607
#17: CBitrixComponent->__includeComponent()
        /home/bitrix/www/bitrix/modules/main/classes/general/component.php:684
#18: CBitrixComponent->includeComponent(string, array, object, boolean)
        /home/bitrix/www/bitrix/modules/main/classes/general/main.php:1072
#19: CAllMain->IncludeComponent(string, string, array, object, array)
        /home/bitrix/www/bitrix/components/bitrix/socialnetwork_group/templates/.default/util_group_menu.php:52
#20: include(string)
        /home/bitrix/www/bitrix/components/bitrix/socialnetwork_group/templates/.default/group.php:99
#21: include(string)
        /home/bitrix/www/bitrix/modules/main/classes/general/component_template.php:790
#22: CBitrixComponentTemplate->__IncludePHPTemplate(array, array, string)
        /home/bitrix/www/bitrix/modules/main/classes/general/component_template.php:885
#23: CBitrixComponentTemplate->IncludeTemplate(array)
        /home/bitrix/www/bitrix/modules/main/classes/general/component.php:775
#24: CBitrixComponent->showComponentTemplate()
        /home/bitrix/www/bitrix/modules/main/classes/general/component.php:716
#25: CBitrixComponent->includeComponentTemplate(string, string)
        /home/bitrix/www/bitrix/components/bitrix/socialnetwork_group/component.php:1215
#26: include(string)
        /home/bitrix/www/bitrix/modules/main/classes/general/component.php:607
#27: CBitrixComponent->__includeComponent()
        /home/bitrix/www/bitrix/modules/main/classes/general/component.php:684
#28: CBitrixComponent->includeComponent(string, array, NULL, boolean)
        /home/bitrix/www/bitrix/modules/main/classes/general/main.php:1072
#29: CAllMain->IncludeComponent(string, string, array)
        /home/bitrix/www/workgroups/index.php:136
#30: include_once(string)
        /home/bitrix/www/bitrix/modules/main/include/urlrewrite.php:160
#31: include_once(string)
        /home/bitrix/www/bitrix/urlrewrite.php:2

———-

 

Пользователь 4490686

Заглянувший

Сообщений: 3
Регистрация: 04.08.2020

#3

05.07.2022 10:29:51

Та же проблема с кодировкой.

Код
1 Object { message: "[Bitrix\Main\ArgumentException] n

JSON error: Malformed UTF-8 characters, possibly incorrectly encoded [5] (100)n

/home/bitrix/www/bitrix/modules/main/lib/web/json.php:160n

#0: Bitrix\Main\Web\Json::throwException(string)n

t/home/bitrix/www/bitrix/modules/main/lib/web/json.php:147n

#1: Bitrix\Main\Web\Json::checkException(integer)n

t/home/bitrix/www/bitrix/modules/main/lib/web/json.php:37n

#2: Bitrix\Main\Web\Json::encode(array, integer)n

t/home/bitrix/www/bitrix/modules/main/lib/engine/respo…main/lib/httpapplication.php:166n

#8: Bitrix\Main\HttpApplication->finalizeControllerResult(object, array, object)n

t/home/bitrix/www/bitrix/modules/main/lib/httpapplication.php:155n

#9: Bitrix\Main\HttpApplication->runController(object, string)n

t/home/bitrix/www/bitrix/modules/main/lib/httpapplication.php:113n

#10: Bitrix\Main\HttpApplication->run()n

t/home/bitrix/www/bitrix/modules/main/services/ajax.php:29n

Как решить? (она появилась после обновления bitrix)

 

Пользователь 4490686

Заглянувший

Сообщений: 3
Регистрация: 04.08.2020

#4

05.07.2022 14:10:04

Проблема с кодировкой . Бывает появляется после обновления сайта.
Чтобы исправить, нужно преобразовать с помощью скрипта в верную кодировку.

https://www.1c-bitrix.ru/download/files/scripts/convert_utf8.php

(если сайт на utf8 был) .
Пример инструкции как делать.

https://dev.1c-bitrix.ru/community/blogs/howto/1466.php

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

json_last_errorReturns the last error occurred

Description

json_last_error(): int

Parameters

This function has no parameters.

Return Values

Returns an integer, the value can be one of the following
constants:

JSON error codes

Constant Meaning Availability
JSON_ERROR_NONE No error has occurred  
JSON_ERROR_DEPTH The maximum stack depth has been exceeded  
JSON_ERROR_STATE_MISMATCH Invalid or malformed JSON  
JSON_ERROR_CTRL_CHAR Control character error, possibly incorrectly encoded  
JSON_ERROR_SYNTAX Syntax error  
JSON_ERROR_UTF8 Malformed UTF-8 characters, possibly incorrectly encoded  
JSON_ERROR_RECURSION One or more recursive references in the value to be encoded  
JSON_ERROR_INF_OR_NAN One or more
NAN
or INF
values in the value to be encoded
 
JSON_ERROR_UNSUPPORTED_TYPE A value of a type that cannot be encoded was given  
JSON_ERROR_INVALID_PROPERTY_NAME A property name that cannot be encoded was given  
JSON_ERROR_UTF16 Malformed UTF-16 characters, possibly incorrectly encoded  

Examples

Example #1 json_last_error() example


<?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;
}
?>

The above example will output:

Decoding: {"Organization": "PHP Documentation Team"} - No errors
Decoding: {'Organization': 'PHP Documentation Team'} - Syntax error, malformed JSON

Example #2 json_last_error() with json_encode()


<?php
// An invalid UTF8 sequence
$text = "xB1x31";$json = json_encode($text);
$error = json_last_error();var_dump($json, $error === JSON_ERROR_UTF8);
?>

The above example will output:

string(4) "null"
bool(true)

Example #3 json_last_error() and JSON_THROW_ON_ERROR


<?php
// An invalid UTF8 sequence which causes JSON_ERROR_UTF8
json_encode("xB1x31");// The following does not cause a JSON error
json_encode('okay', JSON_THROW_ON_ERROR);// The global error state has not been changed by the former json_encode()
var_dump(json_last_error() === JSON_ERROR_UTF8);
?>

The above example will output:

See Also

  • json_last_error_msg() — Returns the error string of the last json_encode() or json_decode() call
  • json_decode() — Decodes a JSON string
  • json_encode() — Returns the JSON representation of a value

jimmetry at gmail dot com

11 years ago


While this can obviously change between versions, the current error codes are as follows:

0 = JSON_ERROR_NONE
1 = JSON_ERROR_DEPTH
2 = JSON_ERROR_STATE_MISMATCH
3 = JSON_ERROR_CTRL_CHAR
4 = JSON_ERROR_SYNTAX
5 = JSON_ERROR_UTF8

I'm only posting these for people who may be trying to understand why specific JSON files are not being decoded. Please do not hard-code these numbers into an error handler routine.


praveenscience at gmail dot com

8 years ago


I used this simple script, flicked from StackOverflow to escape from the function failing:

<?php
   
function utf8ize($d) {
        if (
is_array($d)) {
            foreach (
$d as $k => $v) {
               
$d[$k] = utf8ize($v);
            }
        } else if (
is_string ($d)) {
            return
utf8_encode($d);
        }
        return
$d;
    }
?>

Cheers,
Praveen Kumar!


msxcms at bmforum dot com

5 years ago


use this code with mb_convert_encoding, you can json_encode some corrupt UTF-8 chars

    function safe_json_encode($value, $options = 0, $depth = 512) {
        $encoded = json_encode($value, $options, $depth);
        if ($encoded === false && $value && json_last_error() == JSON_ERROR_UTF8) {
            $encoded = json_encode(utf8ize($value), $options, $depth);
        }
        return $encoded;
    }

    function utf8ize($mixed) {
        if (is_array($mixed)) {
            foreach ($mixed as $key => $value) {
                $mixed[$key] = utf8ize($value);
            }
        } elseif (is_string($mixed)) {
            return mb_convert_encoding($mixed, "UTF-8", "UTF-8");
        }
        return $mixed;
    }


hemono at gmail dot com

7 years ago


when json_decode a empty string, PHP7 will trigger an Syntax error:
<?php
json_decode
("");
var_dump(json_last_error(), json_last_error_msg());// PHP 7
int(4)
string(12) "Syntax error"//  PHP 5
int(0)
string(8) "No error"

George Dimitriadis

6 years ago


Just adding this note since I had to code this for the actual values reference.

<?phpecho JSON_ERROR_NONE . ' JSON_ERROR_NONE' . '<br />';
echo
JSON_ERROR_DEPTH . ' JSON_ERROR_DEPTH' . '<br />';
echo
JSON_ERROR_STATE_MISMATCH . ' JSON_ERROR_STATE_MISMATCH' . '<br />';
echo
JSON_ERROR_CTRL_CHAR . ' JSON_ERROR_CTRL_CHAR' . '<br />';
echo
JSON_ERROR_SYNTAX . ' JSON_ERROR_SYNTAX' . '<br />';
echo
JSON_ERROR_UTF8 . ' JSON_ERROR_UTF8' . '<br />';
echo
JSON_ERROR_RECURSION . ' JSON_ERROR_RECURSION' . '<br />';
echo
JSON_ERROR_INF_OR_NAN . ' JSON_ERROR_INF_OR_NAN' . '<br />';
echo
JSON_ERROR_UNSUPPORTED_TYPE . ' JSON_ERROR_UNSUPPORTED_TYPE' . '<br />';/*
The above outputs :
0 JSON_ERROR_NONE
1 JSON_ERROR_DEPTH
2 JSON_ERROR_STATE_MISMATCH
3 JSON_ERROR_CTRL_CHAR
4 JSON_ERROR_SYNTAX
5 JSON_ERROR_UTF8
6 JSON_ERROR_RECURSION
7 JSON_ERROR_INF_OR_NAN
8 JSON_ERROR_UNSUPPORTED_TYPE
*/
?>


wedge at atlanteans dot net

4 years ago


here is a small updated version of utf8ize that has the following addition :
* It uses iconv instead of utf8_encode for potentially better result.
* It adds the support of objects variable
* It also update array key value (in a case I met I had to utf8ize the key as well as those were generated from a user input value)

Here is the code.

<?php
   
function utf8ize($d) {
        if (
is_array($d)) {
            foreach (
$d as $k => $v) {
                unset(
$d[$k]);
       
$d[utf8ize($k)] = utf8ize($v);
            }
        } else if (
is_object($d)) {
       
$objVars = get_object_vars($d);
        foreach(
$objVars as $key => $value) {
       
$d->$key = utf8ize($value);
        }       
    } else if (
is_string ($d)) {
            return
iconv('UTF-8', 'UTF-8//IGNORE', utf8_encode($d));
        }
        return
$d;
    }
?>


williamprogphp at yahoo dot com dot br

9 years ago


This is a quite simple and functional trick to validate JSON's strings.

<?phpfunction json_validate($string) {
        if (
is_string($string)) {
            @
json_decode($string);
            return (
json_last_error() === JSON_ERROR_NONE);
        }
        return
false;
    }
    echo (
json_validate('{"test": "valid JSON"}')  ? "It's a JSON" : "NOT is a JSON"); // prints 'It's a JSON'
   
echo (json_validate('{test: valid JSON}')  ? "It's a JSON" : "NOT is a JSON"); // prints 'NOT is a JSON' due to missing quotes
   
echo (json_validate(array())  ? "It's a JSON" : "NOT is a JSON"); // prints 'NOT is a JSON' due to a non-string argument
?>

Cheers


Из песочницы, Программирование, PHP


Рекомендация: подборка платных и бесплатных курсов таргетированной рекламе — https://katalog-kursov.ru/

Это краткая статья о наиболее вероятных проблемах с json_encode и их решениях. Иногда при кодировании данных в json, с помощью json_encode в php, мы получаем не тот результат который ожидаем. Я выделил три наиболее частые проблемы с которыми сталкиваются программисты:

  • доступ к полям
  • кодировка текстовых значений
  • цифровые значения

Доступ к полям

Проблема заключается в том что json_encode имеет доступ только к публичным полям объекта. Например если у вас есть класс

class Example {
    public $publicProperty;
    protected $protectedProperty;
    private $privateProperty;

    public function __construct($public, $protected, $private)
    {
        $this->publicProperty = $public;
        $this->protectedProperty = $protected;
        $this->privateProperty = $private;
    }
}

то результатом выполнения следующего кода будет:

$obj = new Example("some", "value", "here"); 
echo json_encode($obj);

// {"publicProperty":"some"}

как видно в результирующий json были включены только публичные поля.
Что же делать если нужны все поля?

Решение

Для php < 5.4:
нам необходимо будет реализовать в классе метод который будет возвращать готовый json. Т.к. внутри класса есть доступ ко всем полям можно сформировать правильное представление объекта для  json_encode

class Example {
    public $publicProperty;
    protected $protectedProperty;
    private $privateProperty;

    public function __construct($public, $protected, $private)
    {
        $this->publicProperty = $public;
        $this->protectedProperty = $protected;
        $this->privateProperty = $private;
    }

    public function toJson()
    {
        return json_encode([
            'publicProperty' => $this->publicProperty,
            'protectedProperty' => $this->protectedProperty,
            'privateProperty' => $this->privateProperty,
        ]);
    }
}

Для получение json-a c объекта теперь нужно пользоваться методом toJson, а не прямым применением json_encode к объекту

$obj = new Example("some", "value", "here"); 
echo $obj->toJson();

Для php >= 5.4:
достаточно будет реализовать интерфейс JsonSerializable для нашего класса, что подразумевает добавление метода jsonSerialize который будет возвращать структуру представляющую объект для json_encode

class Example implements JsonSerializable
{
    public $publicProperty;
    protected $protectedProperty;
    private $privateProperty;

    public function __construct($public, $protected, $private)
    {
        $this->publicProperty = $public;
        $this->protectedProperty = $protected;
        $this->privateProperty = $private;
    }

    public function jsonSerialize() 
    {
        return [
            'publicProperty' => $this->publicProperty,
            'protectedProperty' => $this->protectedProperty,
            'privateProperty' => $this->privateProperty,
        ];
    }
}

Теперь мы можем использовать json_encode как и раньше

$obj = new Example("some", "value", "here"); 
echo json_encode($obj);

// {"publicProperty":"some","protectedProperty":"value","privateProperty":"here"}

Почему не стоит использовать подход с toJson методом?

Многие наверно заметили что подход с созданием метода возвращающего json может быть использован и в версиях php >= 5.4. Так почему же не воспользоваться им? Все дело в том что ваш класс может быть использован как часть иной структуры данных

echo json_encode([
    'status' => true,
    'message' => 'some message',
    'data' => new Example("some", "value", "here"),
]);

и результат уже будет совсем другой.
Также класс может использоваться другими программистами, для которых такой тип получение json-а с объекта может быть не совсем очевиден.

Что если у меня очень много полей в класcе?

В таком случае можно воспользоваться функцией get_object_vars

class Example implements JsonSerializable
{
    public $publicProperty;
    protected $protectedProperty;
    private $privateProperty;
    protected $someProp1;
...
    protected $someProp100500;

    public function __construct($public, $protected, $private)
    {
        $this->publicProperty = $public;
        $this->protectedProperty = $protected;
        $this->privateProperty = $private;
    }

    public function jsonSerialize() 
    {
        $fields = get_object_vars($this);
        // что-то делаем ...
        return $fields;
    }
}

А если нужно private-поля, из класса, который нет возможности редактировать?

Может получиться ситуация когда нужно получить private поля (именно private, т.к. доступ к protected полям можно получить через наследование) в json-е. В таком случае необходимо будет воспользоваться рефлексией:

class Example
{
    public $publicProperty = "someValue";
    protected $protectedProperty;
    private $privateProperty1;
    private $privateProperty2;
    private $privateProperty3;

    public function __construct($privateProperty1, $privateProperty2, $privateProperty3, $protectedProperty)
    {
        $this->protectedProperty = $protectedProperty;
        $this->privateProperty1 = $privateProperty1;
        $this->privateProperty2 = $privateProperty2;
        $this->privateProperty3 = $privateProperty3;
    }
}

$obj = new Example("value1", 12, "21E021", false);
$reflection = new ReflectionClass($obj);

$public = [];

foreach ($reflection->getProperties() as $property) {
    $property->setAccessible(true);
    $public[$property->getName()] = $property->getValue($obj);
}

echo json_encode($public);

//{"publicProperty":"someValue","protectedProperty":false,"privateProperty1":"value1","privateProperty2":12,"privateProperty3":"21E021"}

Кодировка текстовых значений

Кириллица и другие знаки в UTF8

Второй тип распространённых проблем с json_encode это проблемы с кодировкой. Часто текстовые значения которые нужно кодировать в json имеют в себе символы в UTF8 (в том числе кириллица) в результате эти символы будут представлены в виде кодов:

echo json_encode("кириллица or ? ? ? ? ? ? ? ? ? ? $");

// "u043au0438u0440u0438u043bu043bu0438u0446u0430 or u20b3 u0192 u5143 ufdfc u20a8 u0bf9 uffe5 u20b4 uffe1 u0e3f uff04"

Отображение таких символов лечится очень просто — добавлением флага JSON_UNESCAPED_UNICODE вторым аргументом к функции json_encode:

echo json_encode("кириллица or ? ? ? ? ? ? ? ? ? ? $", JSON_UNESCAPED_UNICODE);
// "кириллица or ? ? ? ? ? ? ? ? ? ? $"

Символы в других кодировках

Функция json_encode воспринимает строковые значения как строки в UTF8, что может вызвать ошибку, если кодировка другая. Рассмотрим маленький кусочек кода (данный пример кода максимально упрощен для демонстрации проблемной ситуации)

echo json_encode(["p" => $_GET['p']]);

На первый взгляд ничего не предвещает проблем, да и что здесь может пойти не так? Я тоже так думал. В подавляющем большинстве случаев все будет работать, и по этой причине поиск проблемы занял у меня несколько больше времени, когда я впервые столкнулся с тем что результатом json_encode было false.

Для воссоздания такой ситуации предположим что p=%EF%F2%E8%F6%E0 (на пример: localhost?=%EF%F2%E8%F6%E0 ).
*Переменные в суперглобальных массивах $_GET и $_REQUEST уже декодированы.

$decoded = urldecode("%EF%F2%E8%F6%E0");

var_dump(json_encode($decoded));
// bool(false)

var_dump(json_last_error_msg());
// string(56) "Malformed UTF-8 characters, possibly incorrectly encoded"

Как можно увидеть из ошибки: проблема с кодировкой переданной строки (это не UTF8). Решение проблемы очевидное — привести значение в UTF8

$decoded = urldecode("%EF%F2%E8%F6%E0");
$utf8 = utf8_encode($decoded);

echo json_encode($utf8);
// "ioeoa"

Цифровые значения

Последняя типовая ошибка связана с кодированием числовых значений.

Например:

echo json_encode(["string_float" => "3.0"]);
// {"string_float":"3.0"}

Как известно php не строго типизированный язык и позволяет использовать числа в виде строки, в большинстве случаев это не приводит к ошибкам внутри php приложения. Но так как json очень часто используется для передачи сообщений между приложениями, такой формат записи числа может вызвать проблемы в другом приложении. Желательно использовать флаг JSON_NUMERIC_CHECK:

echo json_encode(["string_float" => "3.0"], JSON_NUMERIC_CHECK);
// {"string_float":3}

Уже лучше. Но как видим «3.0» превратилось в 3, что в большинстве случаев будет интерпретировано как int. Используем еще один флаг JSON_PRESERVE_ZERO_FRACTION для корректного преобразования в float:

echo json_encode(["string_float" => "3.0"], JSON_NUMERIC_CHECK | JSON_PRESERVE_ZERO_FRACTION);
// {"string_float":3.0}

Прошу также обратить внимание на следующий фрагмент кода, что иллюстрирует ряд возможных проблем с json_encode и числовыми значениями:

$data = [
    "0000021", // нули слева
    6.12345678910111213, // много знаков после точки (будет округленно)
    "+81011321515", // телефон
    "21E021", // экспоненциальная запись
];

echo json_encode($data, JSON_NUMERIC_CHECK);
//[
//    21,
//    6.1234567891011,
//    81011321515,
//    2.1e+22
// ]

Спасибо за прочтение.

Буду рад увидеть в комментариях описание проблем, с которыми вы сталкивались, что не были упомянуты в статье

 

Introduction

JSON (JavaScript Object Notation) is a platform and language independent way of serializing objects into plaintext. Because it is often used on web and so is PHP, there is a basic extension for working with JSON in PHP.

Syntax

  • string json_encode ( mixed $value [, int $options = 0 [, int $depth = 512 ]] )
  • mixed json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] )

Parameters

Parameter Details
json_encode
value The value being encoded. Can be any type except a resource. All string data must be UTF-8 encoded.
options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT, JSON_PRESERVE_ZERO_FRACTION, JSON_UNESCAPED_UNICODE, JSON_PARTIAL_OUTPUT_ON_ERROR. The behaviour of these constants is described on the JSON constants page.
depth Set the maximum depth. Must be greater than zero.
json_decode
json The json string being decoded. This function only works with UTF-8 encoded strings.
assoc Should function return associative array instead of objects.
options Bitmask of JSON decode options. Currently only JSON_BIGINT_AS_STRING is supported (default is to cast large integers as floats)
  • json_decode handling of invalid JSON is very flaky, and it is very hard to reliably determine if the decoding succeeded, json_decode returns null for invalid input, even though null is also a perfectly valid object for JSON to decode to. To prevent such problems you should always call json_last_error every time you use it.

Decoding a JSON string

The json_decode() function takes a JSON-encoded string as its first parameter and parses it into a PHP variable.

Normally, json_decode() will return an object of stdClass if the top level item in the JSON object is a dictionary or an indexed array if the JSON object is an array. It will also return scalar values or NULL for certain scalar values, such as simple strings, "true", "false", and "null". It also returns NULL on any error.

// Returns an object (The top level item in the JSON string is a JSON dictionary)
$json_string = '{"name": "Jeff", "age": 20, "active": true, "colors": ["red", "blue"]}';
$object = json_decode($json_string);
printf('Hello %s, You are %s years old.', $object->name, $object->age);
#> Hello Jeff, You are 20 years old.

// Returns an array (The top level item in the JSON string is a JSON array)
$json_string = '["Jeff", 20, true, ["red", "blue"]]';
$array = json_decode($json_string);
printf('Hello %s, You are %s years old.', $array[0], $array[1]);

Use var_dump() to view the types and values of each property on the object we decoded above.

// Dump our above $object to view how it was decoded
var_dump($object);

Output (note the variable types):

class stdClass#2 (4) {
 ["name"] => string(4) "Jeff"
 ["age"] => int(20)
 ["active"] => bool(true)
 ["colors"] =>
   array(2) {
     [0] => string(3) "red"
     [1] => string(4) "blue"
   }
}

Note: The variable types in JSON were converted to their PHP equivalent.


To return an associative array for JSON objects instead of returning an object, pass true as the second parameter to json_decode().

$json_string = '{"name": "Jeff", "age": 20, "active": true, "colors": ["red", "blue"]}';
$array = json_decode($json_string, true); // Note the second parameter
var_dump($array);

Output (note the array associative structure):

array(4) {
  ["name"] => string(4) "Jeff"
  ["age"] => int(20)
  ["active"] => bool(true)
  ["colors"] =>
  array(2) {
    [0] => string(3) "red"
    [1] => string(4) "blue"
  }
}

The second parameter ($assoc) has no effect if the variable to be returned is not an object.

Note: If you use the $assoc parameter, you will lose the distinction between an empty array and an empty object. This means that running json_encode() on your decoded output again, will result in a different JSON structure.

If the JSON string has a «depth» more than 512 elements (20 elements in versions older than 5.2.3, or 128 in version 5.2.3) in recursion, the function json_decode() returns NULL. In versions 5.3 or later, this limit can be controlled using the third parameter ($depth), as discussed below.


According to the manual:

PHP implements a superset of JSON as specified in the original » RFC 4627 — it will also encode and decode scalar types and NULL. RFC 4627 only supports these values when they are nested inside an array or an object.
Although this superset is consistent with the expanded definition of «JSON text» in the newer » RFC 7159 (which aims to supersede RFC 4627) and » ECMA-404, this may cause interoperability issues with older JSON parsers that adhere strictly to RFC 4627 when encoding a single scalar value.

This means, that, for example, a simple string will be considered to be a valid JSON object in PHP:

$json = json_decode('"some string"', true);
var_dump($json, json_last_error_msg());

Output:

string(11) "some string"
string(8) "No error"

But simple strings, not in an array or object, are not part of the RFC 4627 standard. As a result, such online checkers as JSLint, JSON Formatter & Validator (in RFC 4627 mode) will give you an error.

There is a third $depth parameter for the depth of recursion (the default value is 512), which means the amount of nested objects inside the original object to be decoded.

There is a fourth $options parameter. It currently accepts only one value, JSON_BIGINT_AS_STRING. The default behavior (which leaves off this option) is to cast large integers to floats instead of strings.

Invalid non-lowercased variants of the true, false and null literals
are no longer accepted as valid input.

So this example:

var_dump(json_decode('tRue'), json_last_error_msg());
var_dump(json_decode('tRUe'), json_last_error_msg());
var_dump(json_decode('tRUE'), json_last_error_msg());
var_dump(json_decode('TRUe'), json_last_error_msg());
var_dump(json_decode('TRUE'), json_last_error_msg());
var_dump(json_decode('true'), json_last_error_msg());

Before PHP 5.6:

bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"

And after:

NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
bool(true)
string(8) "No error"

Similar behavior occurs for false and null.

Note that json_decode() will return NULL if the string cannot be converted.

$json = "{'name': 'Jeff', 'age': 20 }" ;  // invalid json 

$person = json_decode($json);
echo $person->name;    //  Notice: Trying to get property of non-object: returns null
echo json_last_error();     
#  4 (JSON_ERROR_SYNTAX)
echo json_last_error_msg(); 
#  unexpected character 

It is not safe to rely only on the return value being NULL to detect errors. For example, if the JSON string contains nothing but "null", json_decode() will return null, even though no error occurred.

Encoding a JSON string

The json_encode function will convert a PHP array (or, since PHP 5.4, an object which implements the JsonSerializable interface) to a JSON-encoded string. It returns a JSON-encoded string on success or FALSE on failure.

$array = [
    'name' => 'Jeff',
    'age' => 20,
    'active' => true,
    'colors' => ['red', 'blue'],
    'values' => [0=>'foo', 3=>'bar'],
];

During encoding, the PHP data types string, integer, and boolean are converted to their JSON equivalent. Associative arrays are encoded as JSON objects, and – when called with default arguments – indexed arrays are encoded as JSON arrays. (Unless the array keys are not a continuous numeric sequence starting from 0, in which case the array will be encoded as a JSON object.)

echo json_encode($array);

Output:

{"name":"Jeff","age":20,"active":true,"colors":["red","blue"],"values":{"0":"foo","3":"bar"}}

Arguments

Since PHP 5.3, the second argument to json_encode is a bitmask which can be one or more of the following.

As with any bitmask, they can be combined with the binary OR operator |.

PHP 5.x5.3

JSON_FORCE_OBJECT

Forces the creation of an object instead of an array

$array = ['Joel', 23, true, ['red', 'blue']];
echo json_encode($array);
echo json_encode($array, JSON_FORCE_OBJECT);

Output:

["Joel",23,true,["red","blue"]]
{"0":"Joel","1":23,"2":true,"3":{"0":"red","1":"blue"}}

JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_HEX_QUOT

Ensures the following conversions during encoding:

Constant Input Output
JSON_HEX_TAG < u003C
JSON_HEX_TAG > u003E
JSON_HEX_AMP & u0026
JSON_HEX_APOS ' u0027
JSON_HEX_QUOT " u0022
$array = ["tag"=>"<>", "amp"=>"&", "apos"=>"'", "quot"=>"""];
echo json_encode($array);
echo json_encode($array, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);

Output:

{"tag":"<>","amp":"&","apos":"'","quot":"""}
{"tag":"u003Cu003E","amp":"u0026","apos":"u0027","quot":"u0022"}

PHP 5.x5.3

JSON_NUMERIC_CHECK

Ensures numeric strings are converted to integers.

$array = ['23452', 23452];
echo json_encode($array);
echo json_encode($array, JSON_NUMERIC_CHECK);

Output:

["23452",23452]    
[23452,23452]

PHP 5.x5.4

JSON_PRETTY_PRINT

Makes the JSON easily readable

$array = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
echo json_encode($array);
echo json_encode($array, JSON_PRETTY_PRINT);

Output:

{"a":1,"b":2,"c":3,"d":4}
{
    "a": 1,
    "b": 2,
    "c": 3,
    "d": 4
}

JSON_UNESCAPED_SLASHES

Includes unescaped / forward slashes in the output

$array = ['filename' => 'example.txt', 'path' => '/full/path/to/file/'];
echo json_encode($array);
echo json_encode($array, JSON_UNESCAPED_SLASHES);

Output:

{"filename":"example.txt","path":"/full/path/to/file"}
{"filename":"example.txt","path":"/full/path/to/file"}

JSON_UNESCAPED_UNICODE

Includes UTF8-encoded characters in the output instead of u-encoded strings

$blues = ["english"=>"blue", "norwegian"=>"blå", "german"=>"blau"];
echo json_encode($blues);
echo json_encode($blues, JSON_UNESCAPED_UNICODE);

Output:

{"english":"blue","norwegian":"blu00e5","german":"blau"}
{"english":"blue","norwegian":"blå","german":"blau"}

PHP 5.x5.5

JSON_PARTIAL_OUTPUT_ON_ERROR

Allows encoding to continue if some unencodable values are encountered.

$fp = fopen("foo.txt", "r");
$array = ["file"=>$fp, "name"=>"foo.txt"];
echo json_encode($array); // no output
echo json_encode($array, JSON_PARTIAL_OUTPUT_ON_ERROR);

Output:

{"file":null,"name":"foo.txt"}

PHP 5.x5.6

JSON_PRESERVE_ZERO_FRACTION

Ensures that floats are always encoded as floats.

$array = [5.0, 5.5];
echo json_encode($array);
echo json_encode($array, JSON_PRESERVE_ZERO_FRACTION);

Output:

[5,5.5]
[5.0,5.5]

PHP 7.x7.1

JSON_UNESCAPED_LINE_TERMINATORS

When used with JSON_UNESCAPED_UNICODE, reverts to the behaviour of older PHP versions, and does not escape the characters U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR. Although valid in JSON, these characters are not valid in JavaScript, so the default behaviour of JSON_UNESCAPED_UNICODE was changed in version 7.1.

$array = ["line"=>"xe2x80xa8", "paragraph"=>"xe2x80xa9"];
echo json_encode($array, JSON_UNESCAPED_UNICODE);
echo json_encode($array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS);

Output:

{"line":"u2028","paragraph":"u2029"}
{"line":"
","paragraph":"
"}

Debugging JSON errors

When json_encode or json_decode fails to parse the string provided, it will return false. PHP itself will not raise any errors or warnings when this happens, the onus is on the user to use the json_last_error() and json_last_error_msg() functions to check if an error occurred and act accordingly in your application (debug it, show an error message, etc.).

The following example shows a common error when working with JSON, a failure to decode/encode a JSON string (due to the passing of a bad UTF-8 encoded string, for example).

// An incorrectly formed JSON string
$jsonString = json_encode("{'Bad JSON':xB1x31}");

if (json_last_error() != JSON_ERROR_NONE) {
    printf("JSON Error: %s", json_last_error_msg());
}

#> JSON Error: Malformed UTF-8 characters, possibly incorrectly encoded

json_last_error_msg

json_last_error_msg() returns a human readable message of the last error that occurred when trying to encode/decode a string.

  • This function will always return a string, even if no error occurred.
    The default non-error string is No Error
  • It will return false if some other (unknown) error occurred
  • Careful when using this in loops, as json_last_error_msg will be overridden on each iteration.

You should only use this function to get the message for display, not to test against in control statements.

// Don't do this:
if (json_last_error_msg()){} // always true (it's a string)
if (json_last_error_msg() != "No Error"){} // Bad practice

// Do this: (test the integer against one of the pre-defined constants)
if (json_last_error() != JSON_ERROR_NONE) {
    // Use json_last_error_msg to display the message only, (not test against it)
    printf("JSON Error: %s", json_last_error_msg());
}

This function doesn’t exist before PHP 5.5. Here is a polyfill implementation:

if (!function_exists('json_last_error_msg')) {
    function json_last_error_msg() {
        static $ERRORS = array(
            JSON_ERROR_NONE => 'No error',
            JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
            JSON_ERROR_STATE_MISMATCH => 'State mismatch (invalid or malformed JSON)',
            JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
            JSON_ERROR_SYNTAX => 'Syntax error',
            JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded'
        );

        $error = json_last_error();
        return isset($ERRORS[$error]) ? $ERRORS[$error] : 'Unknown error';
    }
}

json_last_error

json_last_error() returns an integer mapped to one of the pre-defined constants provided by PHP.

Constant Meaning
JSON_ERROR_NONE No error has occurred
JSON_ERROR_DEPTH The maximum stack depth has been exceeded
JSON_ERROR_STATE_MISMATCH Invalid or malformed JSON
JSON_ERROR_CTRL_CHAR Control character error, possibly incorrectly encoded
JSON_ERROR_SYNTAX Syntax error (since PHP 5.3.3)
JSON_ERROR_UTF8 Malformed UTF-8 characters, possibly incorrectly encoded (since PHP 5.5.0)
JSON_ERROR_RECURSION One or more recursive references in the value to be encoded
JSON_ERROR_INF_OR_NAN One or more NAN or INF values in the value to be encoded
JSON_ERROR_UNSUPPORTED_TYPE A value of a type that cannot be encoded was given

Using JsonSerializable in an Object

PHP 5.x5.4

When you build REST API’s, you may need to reduce the information of an object to be passed to the client application. For this purpose, this example illustrates how to use the JsonSerialiazble interface.

In this example, the class User actually extends a DB model object of a hypotetical ORM.

class User extends Model implements JsonSerializable {
    public $id;
    public $name;
    public $surname;
    public $username;
    public $password;
    public $email;
    public $date_created;
    public $date_edit;
    public $role;
    public $status;

    public function jsonSerialize() {
        return [
            'name' => $this->name,
            'surname' => $this->surname,
            'username' => $this->username
        ];
    }
}

Add JsonSerializable implementation to the class, by providing the jsonSerialize() method.

public function jsonSerialize()

Now in your application controller or script, when passing the object User to json_encode() you will get the return json encoded array of the jsonSerialize() method instead of the entire object.

json_encode($User);

Will return:

{"name":"John", "surname":"Doe", "username" : "TestJson"}

properties values example.

This will both reduce the amount of data returned from a RESTful endpoint, and allow to exclude object properties from a json representation.


Using Private and Protected Properties with json_encode()

To avoid using JsonSerializable, it is also possible to use private or protected properties to hide class information from json_encode() output. The Class then does not need to implement JsonSerializable.

The json_encode() function will only encode public properties of a
class into JSON.

<?php

class User {
    // private properties only within this class
    private $id;
    private $date_created;
    private $date_edit;

    // properties used in extended classes
    protected $password;
    protected $email;
    protected $role;
    protected $status;

    // share these properties with the end user        
    public $name;
    public $surname;
    public $username;

    // jsonSerialize() not needed here
}        

$theUser = new User();

var_dump(json_encode($theUser));

Output:

string(44) "{"name":null,"surname":null,"username":null}"

Header json and the returned response

By adding a header with content type as JSON:

<?php
 $result = array('menu1' => 'home', 'menu2' => 'code php', 'menu3' => 'about');

//return the json response :
header('Content-Type: application/json');  // <-- header declaration
echo json_encode($result, true);    // <--- encode
exit();

The header is there so your app can detect what data was returned and how it should handle it.
Note that : the content header is just information about type of returned data.

If you are using UTF-8, you can use :

header("Content-Type: application/json;charset=utf-8");

Example jQuery :

$.ajax({
        url:'url_your_page_php_that_return_json'        
    }).done(function(data){
        console.table('json ',data);
        console.log('Menu1 : ', data.menu1);
    });

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Json error cyclic dependency detected
  • Json error 6002 энт
  • Json error 6002 entpro
  • Json error 500 internal server error
  • Json deserialization error

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии