Проблема найдена
Кажется, проблема в том, что $mysqli->set_charset()
не принимает utf8mb4 в качестве допустимой кодировки (как я и предполагал в первом обновлении). Версия MySQL 5.5.41 и версия PHP 5.4.41 (с этим проблем нет).
Извините за заголовок, я искал / читал о том, что / где может быть проблема, и я уже слишком запутался по этому поводу …
Я недавно начал использовать utf8mb4 в MySQL. Я использую utf8mb4 в качестве charset и utf8mb4_unicode_ci в качестве сопоставления для всех таблиц / столбцов.
Поэтому я сначала менял:
$mysqli->set_charset('utf8');
в
$mysqli->set_charset('utf8mb4');
удостоверился, что мои php файлы имеют utf8 (я использую код Visual Studio, поэтому файлы создаются в UTF-8 по умолчанию), а заголовки php / html установлены в utf8:
index.php
header('Content-type: Text/HTML; Charset=UTF-8');
main.php (включен в конец index.php)
<meta http-equiv="Content-Type" content="Text/HTML" />
<meta charset="UTF-8" />
Проблема в том, что для некоторых таблиц мне нужно вручную вставлять данные, и эти данные хранятся как есть: со специальными символами, с акцентами, — и т. Д. И когда я отображаю эти данные на своем веб-сайте, я вижу, что эти персонажи �
заменили специальные / акцентированные символы.
Итак, мой вопрос: есть ли способ хранить данные как есть (без замены / преобразования специальных / акцентированных символов) в mysql и иметь возможность отображать их нормально (как есть)?
Если я вернусь к $mysqli->set_charset('utf8');
данные отображаются нормально … Так что меня удивляет, что не должно быть проблем с сохранением символов utf-8, как они есть, и где-то есть проблема с кодификацией …
Я использую сообщество sqlyog (с вином) и я где-то читал, что иногда графический интерфейс не работает правильно, когда вы изменяете некоторую конфигурацию БД / таблицы, и единственный способ — это старый способ (выполнение запроса самостоятельно), но я еще не пробовал это. Я запустил запросы, чтобы установить кодировку и сопоставление всех таблиц / столбцов.
Как вы думаете?
ОБНОВИТЬ
Я начинаю думать, что mysqli не принимает utf8mb4 в качестве допустимой кодировки символов и использует utf8 из php, а не из mysql … Я также думаю, что mysql fckd создает вместо utf8mb4 вместо обновления существующего utf8 для поддержки 4 байтов … ,
Поскольку я тестирую с mysqli charset utf8, все сохраняется как есть и отображается как есть (с mysql charset и collation, установленным в utf8mb4 …).
ОБНОВЛЕНИЕ 2
SELECT name, HEX(name) FROM person LIMIT 1
Вот что он выводит:
New Person has name Altaïr 416C7461C3AF72
Но, как я уже сказал, это использует:
$mysqli->set_charset('utf8');
вставить и выбрать. Если вместо этого я использую utf8mb4, это то, что хранится:
Altaïr
Но отображается нормально. То, что не отображается нормально, если имя хранится как есть, отображаемое имя будет Alta�r
,
Вопрос в том, почему хранится mysqli / mysql. ï
как ï
используя utf8mb4? И почему php отображает специальные символы, такие как ï
как �
когда utf8mb4 установлен в mysqli?
Может кто-нибудь, пожалуйста, подтвердите, что mysqli::set_charset
принимает utf8mb4 в качестве допустимой кодировки?
ОБНОВЛЕНИЕ 3
У меня есть функция класса, которая выбирает строку из таблицы «es», например: Iniciar Sesión
(это то, что хранится), и если mysqli charset имеет значение utf8, то то, что выбирается / отображается Iniciar Sesión
,
Это может быть совсем другая проблема, но это явно другая проблема кодификации. Насколько я понимаю, если таблицы / столбцы имеют utf8mb4, а mysqli установлен в utf8, mysql должен кодировать от utf8 (3 байта) до ut8mb4 (полная поддержка байтов). Так что это означает, что mysqli
не использует utf8 из php, но из mysql. Это правильно, верно?
Мое приложение в настоящее время испытывает трудности с кодировками … (но, возможно, из-за некоторых проблем с настройкой сервера …)
ОБНОВЛЕНИЕ 4
Может ли проблема быть здесь? Я действительно понятия не имею о таких конфигурациях:
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
+--------------------------+--------------------+
| Variable_name | Value |
+--------------------------+--------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| collation_connection | utf8_general_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | latin1_swedish_ci |
+--------------------------+--------------------+
10 rows in set (0.00 sec)
ОБНОВЛЕНИЕ 4-1 / 2 (скопировано из комментария)
CREATE TABLE `es` (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
text varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY name (name)
) ENGINE=InnoDB AUTO_INCREMENT=76 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`
Проблема может быть связана с тем, что вы не используете utf8mb4
в вашем определении столбца MySQL (по крайней мере, вы не сказали, какую кодировку вы используете).
Вот пример определения таблицы MySQL со столбцом, который использует utfmb4
:
CREATE TABLE `person` (
`name` varchar(255) CHARACTER SET utf8mb4
)
ОБНОВИТЬ
Используя следующее определение таблицы:
CREATE TABLE `person` (
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
и следующий скрипт PHP:
<?php
$mysqli = new mysqli('localhost', 'username', 'password', 'database');
$mysqli->set_charset('utf8mb4');
$mysqli->query("INSERT INTO `person` VALUES ('Altaïr Ibn-La\'Ahad')");
$result = $mysqli->query("SELECT * FROM `person` LIMIT 1");
$person = $result->fetch_object();
if($person)
printf ("New Person has name %s.\n", $person->name);
$result->close();
$mysqli->close();
Когда я вставляю «Altaïr Ibn-La’Ahad» в базу данных, имя сохраняется без изменений. Скрипт также печатает имя без изменений:Новый человек имеет имя Альтаир Ибн-Ла-Ахад.«
Я надеюсь, что это поможет вам решить вашу проблему. Дайте мне знать, если это так или нет.
utf8mb4 Altaïr 41 6C 74 61 C383C2AF 72
Уч. Это «двойное кодирование». latin1 EF
был преобразован в utf8 / utf8mb4 C3AF
; затем C3
, неправильно трактуется как латиница 1 был преобразован в C383
а также AF
в C2AF
,
Вот что, вероятно, произошло:
SET NAMES latin1
солгал, утверждая, что у клиента была латинская кодировка; а такжеCHARACTER SET utf8
(или utf8mb4) (хорошо).Этот второй шаг должен были исправлены
$mysqli->set_charset('utf8mb4');
Я полагаю, вы не смешиваете mysql_*
а также mysqli_*
интерфейсы. Используйте только последнее.
Как насчет публикации короткого, воспроизводимого тестового примера?
Мистери решил! Произошла неправильная установка / обновление / конфигурация с mysql, и utf8mb4 не был правильно установлен.
Проблема с функцией заключалась в том, что она перекодировала значения БД с помощью utf8_encode () и каким-то образом вызывала подобные символы ó
-> ó
,