Управление данными utf8mb4 из MySQL с помощью PHP

Это, вероятно, что-то простое. Клянусь, я искал ответ в интернете и не нашел его. Поскольку мой конкретный случай немного нетипичен, я, наконец, решил спросить Здесь.

У меня есть несколько таблиц в MySQL, которые я использую для программы на китайском языке. Он должен поддерживать все возможные китайские символы, включая редкие, которые не имеют большой поддержки шрифтов. Пример ячейки в таблице может быть следующим:

東菄鶇䍶

2 ответов


Я бы просто догадался, что вы устанавливаете стол на utf8mb4, но кодировка соединения установлена в utf8. Вы должны установить его в utf8mb4 также, в противном случае MySQL преобразует сохраненный utf8mb4 данные utf8, последний из которых не может кодировать "высокие" символы Юникода. (Да,это особенность MySQL.)

на необработанном соединении MySQL он должен будет выглядеть так:

SET NAMES 'utf8mb4';
SELECT * FROM `my_table`;

вам придется адаптировать это к лучшему способу клиента, в зависимости от как вы подключаетесь к MySQL из PHP (mysql, mysqli или PDO).


чтобы действительно уточнить (да, используя


чтобы добавить к ответу @deceze, я рекомендую хорошо настроенный сервер MySQL (для меня, в /etc/mysql/mysql.conf.d/mysqld.cnf). Вот параметры конфигурации, чтобы убедиться, что вы используете utfmb4, хотя я рекомендую пройти через каждый параметр конфигурации MySQL, хотя, как это ни сложно, есть много значений по умолчанию, которые очень неоптимальны.

[client]

default-character-set           = utf8mb4

[mysql]

default_character_set           = utf8mb4

[mysqld]

init-connect                    = "SET NAMES utf8mb4"
character-set-client-handshake  = FALSE
character-set-server            = "utf8mb4"
collation-server                = "utf8mb4_unicode_ci"
autocommit                      = 1
block_encryption_mode           = "aes-256-cbc"

это последний, который должен быть по умолчанию. Кроме того,init-connect имеет дело с тем, чтобы не выполнять это каждый раз. Сохраняет код в чистоте. Теперь беги:

SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';

вы должны вернуть что-то вроде следующего:

+--------------------------+--------------------+
| Variable_name            | Value              |
+--------------------------+--------------------+
| character_set_client     | utf8mb4            |
| character_set_connection | utf8mb4            |
| character_set_database   | utf8mb4            |
| character_set_filesystem | binary             |
| character_set_results    | utf8mb4            |
| character_set_server     | utf8mb4            |
| character_set_system     | utf8               |
| collation_connection     | utf8mb4_unicode_ci |
| collation_database       | utf8mb4_unicode_ci |
| collation_server         | utf8mb4_unicode_ci |
+--------------------------+--------------------+

и похоже, что вы уже делаете это, но не помешает явно определить при создании таблицы:

CREATE TABLE `mysql_table` (
  `mysql_column` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`mysql_column`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4;

надеюсь, это кому-то поможет.