PHP вставляет японскую строку в таблицу utf8 как-то еще, но все равно успешно читает

Почему PHP хранит такие символы, как японский, в таблице MySQL, которая поддерживает utf8 как-то еще, но успешно считывает значение обратно из MySQL как исходную строку?

Например

$db = new mysqli("localhost", "user", "pwd", "test");
$sql = "INSERT INTO testtable(name) VALUES ('ボーナスエリア');

Из верстака это было вставлено в таблицу как ãƒ‡ã‚£ã‚·ãƒ§ãƒ³Я понятия не имею, как или на каком уровне происходит кодирование / отображение.

Чтение его обратно в PHP приводит к правильной строке ボーナスエリア отображается на веб-странице. Почему и как это работает?

ОБНОВЛЕНИЕ Спасибо за все комментарии до сих пор. Больше, чем просто любопытство, это фактически вызывает у меня проблему с желанием вставить символы из другого источника, то есть Java, который через jdbc правильно вставляет символы CJK. Это вызывает проблемы в PHP, читая их обратно и отображая как??????

Кто-нибудь может доказать, какая кодировка переводит данные символы в то, что появляется в db viewer?

ОБНОВЛЕНИЕ 2 Мой браузер (который не имеет ничего общего с этой проблемой, так как значение отображается перед отображением) - это firefox с кодировкой Western ISO-8859-1. Я вижу, что японские символы отображаются правильно рядом с????? персонажи. Как ни парадоксально, персонажи, которые появляются как???? правильно отображаются в db viewer.

Настройки браузера

настройки браузера

Фрагмент веб-страницы

фрагмент веб-страницы

1 ответ

Решение

PHP обрабатывает текст в основном как произвольные двоичные данные. Это означает, что в этих случаях довольно часто две ошибки компенсируют друг друга.

Например, если вы пишете ボーナスエリア в исходном файле и сохраните его в UTF-8, что PHP видит байты \xe3\x83\x9c\xe3\x83\xbc... и вот с чем он будет работать. Вы можете передать эту строку в клиентскую библиотеку базы данных, как здесь, чтобы mysqliи, если вам повезет, когда вы позже получите текст из базы данных, клиентская библиотека вернет те же самые байты в PHP. Независимо от того, как база данных фактически хранит данные.

Похоже, что здесь происходит то, что клиентская библиотека базы данных сконфигурирована для интерпретации данных руками PHP в соответствии с latin1, что означает, что она интерпретирует байты \xe3\x83\x9c... как персонажи デ...и это то, что база данных будет хранить. Когда вы читаете данные, происходит то же самое: клиент получает символы デ... из базы данных, и так как он настроен на их кодирование в latin1, он вернет \xe3\x83\x9c... в PHP. Это объясняет, как вы можете иметь mojibake в базе данных, но приложение PHP по-прежнему работает нормально.

Конечно, было бы лучше, чтобы база данных сохраняла текст в удобочитаемом формате. Для этого вы должны установить кодировку клиента (см. Mysqli_set_charset) и кодировку столбца базы данных (см. Документацию MySQL) в utf8,

Другие вопросы по тегам