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
,