php пытается выдать ошибку, но только если вы отключите display_errors . Это странно, потому что настройка display_errors
предназначена только для контроля того, будут ли ошибки выводиться на стандартный вывод, а не на то, была ли вызвана ошибка. Я хочу подчеркнуть, что когда вы включаете display_errors
, хотя вы можете видеть все виды других ошибок php, php не просто скрывает эту ошибку, даже не вызывает ее . Это означает, что он не будет отображаться ни в каких журналах ошибок, и не будут вызываться какие-либо пользовательские обработчики ошибок. Ошибка просто никогда не возникает.
Вот код, демонстрирующий это:
error_reporting(-1);//report all errors
$invalid_utf8_char = chr(193);
ini_set('display_errors', 1);//display errors to standard output
var_dump(json_encode($invalid_utf8_char));
var_dump(error_get_last());//nothing
ini_set('display_errors', 0);//do not display errors to standard output
var_dump(json_encode($invalid_utf8_char));
var_dump(error_get_last());// json_encode(): Invalid UTF-8 sequence in argument
Это странное и неудачное поведение связано с этой ошибкой https://bugs.php.net/bug.php?id=47494 и некоторыми другими, и не похоже, что она когда-либо будет исправлена.
Обойти:
Очистка строки перед передачей ее в json_encode может быть приемлемым решением.
$stripped_of_invalid_utf8_chars_string = iconv('UTF-8', 'UTF-8//IGNORE', $orig_string);
if ($stripped_of_invalid_utf8_chars_string !== $orig_string) {
// one or more chars were invalid, and so they were stripped out.
// if you need to know where in the string the first stripped character was,
// then see http://stackoverflow.com/questions/7475437/find-first-character-that-is-different-between-two-strings
}
$json = json_encode($stripped_of_invalid_utf8_chars_string);
http://php.net/manual/en/function.iconv.php
В инструкции написано
//IGNORE
молча отбрасывает недопустимых в цель символов
набор символов.
Итак, сначала удалив проблемные символы, в теории json_encode () не должен получить ничего, что он захлебнется и потерпит неудачу. Я не проверял, что вывод iconv с флагом //IGNORE
полностью совместим с понятием json_encodes того, что представляют собой действительные символы utf8, так что покупатель остерегается ... поскольку могут быть крайние случаи, когда он все еще не работает. тьфу, я ненавижу проблемы с набором символов.
Редактировать
в php 7.2+ появились новые флаги для json_encode
:
JSON_INVALID_UTF8_IGNORE
и JSON_INVALID_UTF8_SUBSTITUTE
Документации пока немного, но сейчас этот тест должен помочь вам понять ожидаемое поведение:
https://github.com/php/php-src/blob/master/ext/json/tests/json_encode_invalid_utf8.phpt
И в php 7.3+ появился новый флаг JSON_THROW_ON_ERROR
. См http://php.net/manual/en/class.jsonexception.php