Laravel - Json Encode работает нормально, но все равно возвращает искаженную ошибку UTF-8

Проблема

JSON возвращается правильно закодированным, но json_last_error соответствует 5, поэтому Laravel выдает это исключение при создании ответа в JsonResponse->setData().

Связанные ссылки

Решенный отчет об ошибке для symfony и PHP 7.3: https://github.com/symfony/symfony/issues/31447 упоминает именно эту проблему. То есть:

If a json_encode()/json_decode() without JSON_THROW_ON_ERROR encoding option set throws an error, any subsequent call to the same with that flag set will not reset the error of the previous call.

В JSON_THROW_ON_ERROR RFC такое поведение упоминается как преднамеренное: https://wiki.php.net/rfc/json_throw_on_error< /а>

К сожалению, код Laravel использует флаг, но не учитывает такое поведение и выдает исключение, если json_last_error() возвращает ненулевое значение. Который в этом случае должен был быть проигнорирован, поскольку он всегда будет ссылаться на предыдущую ошибку. Возможно, стоит добавить проверку версии.

Расследование

Я также обыскал чаши своего приложения и не нашел неправильного поведения json_encode/json_decode без набора JSON_THROW_ON_ERROR, поэтому я уверен, что он является внутренним для Laravel до вызовов промежуточного программного обеспечения.

Дополнительный контекст

Это внезапно начало происходить сегодня на нашем сервере. Это происходит, когда пользователи подключаются к серверу через веб-приложение из некоторых систем. Несмотря на то, что тип системы не должен влиять на генерацию ответа на стороне сервера, веб-приложение всегда генерирует эту ошибку для определенных ПК/мобильных устройств.


person Umair Ahmed    schedule 03.07.2020    source источник


Ответы (1)


Предлагаемый взлом

После просмотра отчета об ошибках Symfony, самый простой обходной путь, который я нашел, — это просто сбросить ошибку с помощью несущественного вызова json_encode('1'). Что эффективно сбрасывает код ошибки на 0, и более поздние методы JSON работают нормально.

К счастью, у нас есть собственный класс генерации ответов, поэтому простое добавление его перед передачей в Laravel работает нормально.

Все равно это хак. Меня больше интересует лучшее решение или любое исправление ошибки.

person Umair Ahmed    schedule 03.07.2020