1. Главная страница » Компьютеры » Mysql set charset utf 8

Mysql set charset utf 8

Автор: | 16.12.2019

На данный вопрос уже ответили:

Результат sql-запроса возвращается не в UTF-8 кодировке. Пытался установить кодировку с помощью функции mysql_set_charset(‘utf8’,$db) , но по все видимости функция не работает, при том, что MySQL версии 5.0.7. Как можно по другому задать кодировку соединения, но не используя SET NAMES ?

З.Ы. Когда работал с той же таблицей при помощи PDO , при установке кодировки:

Поля возвращались в UTF-8 .

Отмечен как дубликат участником Ипатьев php Участники со знаками php могут единолично закрывать вопросы с меткой php как дубликаты, а также повторно открывать их при необходимости. 26 окт ’17 в 12:35 .

Подобный вопрос задавали ранее и на него уже получен ответ. Если представленные ответы не являются исчерпывающими, пожалуйста, задайте новый вопрос.

5 ответов 5

Самый 100%ый код для 100%ого UTF-8 😀

    Оригинальное API MySQL (функции mysql_ ) устарело, начиная с версии PHP 5.5.0, и удалено в PHP 7.0.0.

Для улучшенного модуля MySQL (MySQL Improved) предпочтительным способом является использование метода set_charset().

Использование для этих целей метода query() (например: SET NAMES ‘utf8’ ) не рекомендуется.

В PDO следует указывать кодировку соединения в параметре dsn при создании экземпляра класса работы с бд:

(PHP 5 >= 5.0.5, PHP 7)

mysqli::set_charset — mysqli_set_charset — Задает набор символов по умолчанию

Описание

Задает набор символов по умолчанию, который будет использоваться при обмене данными с сервером баз данных.

Список параметров

Только для процедурного стиля: Идентификатор соединения, полученный с помощью mysqli_connect() или mysqli_init()

Набор символов, который необходимо установить.

Возвращаемые значения

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.

Примечания

Чтобы использовать эту функцию на Windows платформах, вам потребуется клиентская библиотека MySQL версии 4.1.11 или выше (для MySQL 5.0 соответственно 5.0.6 или выше).

Это предпочтительный способ задания набора символов. Использование для этих целей функции mysqli_query() (например SET NAMES utf8) не рекомендуется. Дополнительно см. Наборы символов в MySQL.

Примеры

Пример #1 Пример использования mysqli::set_charset()

= new mysqli ( "localhost" , "my_user" , "my_password" , "test" );

/* проверка соединения */
if ( mysqli_connect_errno ()) <
printf ( "Не удалось подключиться: %s
" , mysqli_connect_error ());
exit();
>

printf ( "Изначальная кодировка: %s
" , $mysqli -> character_set_name ());

/* изменение набора символов на utf8 */
if (! $mysqli -> set_charset ( "utf8" )) <
printf ( "Ошибка при загрузке набора символов utf8: %s
" , $mysqli -> error );
exit();
> else <
printf ( "Текущий набор символов: %s
" , $mysqli -> character_set_name ());
>

= mysqli_connect ( ‘localhost’ , ‘my_user’ , ‘my_password’ , ‘test’ );

/* проверка соединения */
if ( mysqli_connect_errno ()) <
printf ( "Не удалось подключиться: %s
" , mysqli_connect_error ());
exit();
>

printf ( "Изначальная кодировка: %s
" , $mysqli -> character_set_name ());

/* изменение набора символов на utf8 */
if (! mysqli_set_charset ( $link , "utf8" )) <
printf ( "Ошибка при загрузке набора символов utf8: %s
" , mysqli_error ( $link ));
exit();
> else <
printf ( "Текущий набор символов: %s
" , mysqli_character_set_name ( $link ));
>

Результат выполнения данных примеров:

Смотрите также

  • mysqli_character_set_name() — Возвращает кодировку по умолчанию, установленную для соединения с БД
  • mysqli_real_escape_string() — Экранирует специальные символы в строке для использования в SQL-выражении, используя текущий набор символов соединения
  • Концепции кодировок MySQL
  • » Список поддерживаемых MySQL наборов символов

User Contributed Notes 7 notes

Setting the charset (it’s really the encoding) like this after setting up your connection:
$connection->set_charset("utf8mb4")

FAILS to set the proper collation for the connection:

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_general_ci query("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci");

Читайте также:  Huawei ec 5321u 2

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

So in my case, I had tried changing the collation from utf8mb4_unicode_ci for mysql and had to change it to uft8_general_ci.

mysqli_set_charset( $con, ‘utf8’);

right before I did the SELECT command.

This is my code for reading from db :

$con = mysqli_connect($DB_SERVER, $DB_USER_READER, $DB_PASS_READER, $DB_NAME, $DB_PORT);//this is the unique connection for the selection

mysqli_set_charset( $con, ‘utf8’);

$slct_stmnt = "SELECT ".$SELECT_WHAT." FROM ".$WHICH_TBL." WHERE ".$ON_WHAT_CONDITION;

$slct_query = mysqli_query($con, $slct_stmnt);

if ($slct_query==true) <
//Do your stuff here . . .
>

And it worked like a charm. All the best. The above code can work with reading chineese, russian or arabic or any international language from the database’s table column holding such data.

To align both the character set (e.g., utf8mb4) AND the collation sequence with the schema (database) settings:

= new mysqli ( DB_HOST , DB_USER , DB_PASSWORD , DB_SCHEMA , DB_PORT );
if ( 0 !== $mysqli -> connect_errno )
throw new Exception ( $mysqli -> connect_error , $mysqli -> connect_errno );

if ( TRUE !== $mysqli -> set_charset ( ‘utf8mb4’ ) )
throw new Exception ( $mysql -> error , $mysqli -> errno );

if ( TRUE !== $mysqli -> query ( ‘SET collation_connection = @@collation_database;’ ) )
throw new Exception ( $mysql -> error , $mysqli -> errno );
?>

To confirm:

echo ‘character_set_name: ‘ , $mysqli -> character_set_name (), ‘
‘ , PHP_EOL ;
foreach( $mysqli -> query ( "SHOW VARIABLES LIKE ‘%_connection’;" )-> fetch_all () as $setting )
echo $setting [ 0 ], ‘: ‘ , $setting [ 1 ], ‘
‘ , PHP_EOL ;
?>

will output something like:
character_set_name: utf8mb4
character_set_connection: utf8mb4
collation_connection: utf8mb4_unicode_520_ci

Although the documentation says that using that function is preferred than using SET NAMES, it is not sufficient in case you use a collation different from the default one:

// That will reset collation_connection to latin1_swedish_ci
// (the default collation for latin1):
$mysqli -> set_charset ( ‘latin1’ );

// You have to execute the following statement *after* mysqli::set_charset()
// in order to get the desired value for collation_connection:
$mysqli -> query ( "SET NAMES latin1 COLLATE latin1_german1_ci" );

Note that using utf8mb4 with this function may cause this function to return false, depending on the MySQL client library compiled into PHP. If the client library is older than the introduction of utf8mb4, then PHP’s call of the libraries ‘mysql_set_character_set’ will return an error because it won’t recognise that character set.

The only way you will know there’s an error is by checking the return value, because PHP warnings are not emitted by this function.
mysqli_error will return something like:
"Can’t initialize character set utf8mb4 (path: /usr/share/mysql/charsets/)"
(I don’t think the directory has anything to do with it; I think the utf8mb4 vs utf8 distinction is handled internally)

A workaround is to recall with utf8, then do a ‘SET NAMES’ query with utf8mb4.

If your MySQL server is configured to use utf8 by default, then you may not notice any of this until you get obscure bugs. It seems it will still save into the database correctly in terms of bytes. However, you may get "Data too long for column" errors if you are truncating strings to fit fields, because from MySQL’s point of view during the length check every 4-byte character will actually be multiple individual characters. This caused me hours of debugging.

Сегодня речь пойдет о MySQL и о настройке UTF8 кодировки по-умолчанию. Тема заезжена, но как я убедился за прошедшую неделю, мало кто в состоянии нормально пояснить какие параметры и куда надо прописать для полноценной работы с UTF8 в MySQL. К сожалению, ситуация на тематических блогах оставляет желать лучшего. Основной тип ответа — приведение соедржимого конфигурационного файла с комментарием типа “попробуй, у меня это работает”.

Основная цель данного поста — выяснить, какие параметры и с какими значениями следует прописать в конфигурационный файл my.cnf (my.ini) для дальнейшей беспроблемной работы с Юникодом.

Рабочее окружение

UTF8 на данный момент у меня успешно работает в Мастер-Слейв конфигурации:

  • MySQL версии 5.1.66
  • Два сервера CentOS версии 6.3
  • Репликация между серверами Master-Slave на базе SSL

Любой внешний клиент в состоянии корректно работать с UTF8 базой (проверено на EMS Manager for MySQL c Windows 8 x64).

Читайте также:  Lenovo b570e не работает wifi

Все опции и настройки я привожу для версии сервера 5.1.x, однако с минимальными (а то и вовсе без оных) изменениями все это будет работать и на версиях 5.5.x и 5.6.x.

Параметры кодировок MySQL

Довольно часто приходится видеть в ответах на вопросы о настройке UTF8 следующее:

Предполагается, что после вставки всего этого добра (тут кстати есть противоречащие друг другу опции) в конфигурационный файл my.cnf (my.ini) магический Юникод начнет работать.

Но давайте забудем о списке и попытаемся разбираться со всеми опциями сами и начнем с самого начала. То есть с документации. Потому как все это прекрасно описано в документации MySQL на официальном сайте. Я лишь постараюсь последовательно рассказать о параметрах сервера и прояснить неясные моменты.

Главный раздел по описанию кодировок (character sets) и их представлений (collations — используется например при сортировке) в контексте сервера, базы, таблиц — это секция 10.1.3. Specifying Character Sets and Collations.

Символьная кодировка может быть задана для:

  1. сервера,
  2. базы данных,
  3. таблицы и
  4. колонок в таблице.

Сделано это для гибкой настройки баз данных и доступа клиентов с разными кодировками. Однако, последнее не входит в область рассмотрения данного поста, поэтому будем рассматривать вариант с кодировкой UTF8 настроенной для всего по-умолчанию.

Все параметры могут быть переданы серверу тремя разными способами:

  1. через командную строку mysqld
  2. через конфигурационный файл my.cnf (my.ini)
  3. через опции компиляции.

Второй и третий варианты рассматриваться не будут. Тут уместно будет просто прочитать официальные доки — в каждом разделе приведены примеры конфигурации с использованием всех трех способов. Я же буду использовать первый вариант.

Кодировка (character set) и представление (collation) сервера

Кодировка (characher set) — набор используемых символов.
Представление (collation) — набор правил для сравнения символов в наборе.

Тут есть несколько фундаментальных вещей которые надо понимать.

Основные параметры используемые в контексте сервера — это character_set_server и collation_server . Оба параметра влияют на определение кодировки и отображения сервера MySQL.

Можно задать оба параметра либо только один из них. При этом важно знать как задача того или иного влияет на определение отсутствующего:

Не заданы — используются значения по умолчанию (дефолтные),

Заданы оба — используются указанные кодировка и ее представление,

Задана только кодировка — ее представление выставляется по умолчанию для данного типа кодировки. Что это значит? Для каждого типа кодировки есть ее дефолтное представление, например, дефолтная кодировка сервера — latin1 , а дефолтное отображение для нее — latin1_swedish_ci . Посмотреть соответствие кодировки и ее дефолтного представления можно используя команду:

SHOW COLLATION LIKE ‘your_character_set_name’;

Поле Default дает ответ о представлении выбранной кодировки.

В нашем случае, при настройке дефолтной кодировки в UTF8, параметры должны быть определены, так как могут быть использованы при определении кодировки или представления базы данных:

Наши команды:
my.cnf (my.ini)

[mysqld]
character-set-server = utf8
collation-server = utf8_unicode_ci

Дефолтное представление для utf8 — utf8_general_ci , так что если бы мы его использовали вместо utf8_unicode_ci , то параметр collation_server можно было бы вообще опустить.

Кодировка (character set) и представление (collation) базы данных

Тут есть два варианта определения кодировки и представления:

явно — при выполнении запроса на создание базы данных:

CREATE DATABASE db_name CHARACTER SET latin1 COLLATE latin1_swedish_ci;

неявно через переменные character_set_database и collation_database . Однако, эти переменные нельзя задать явно ни в командной строке ни в конфигурационном файле. Как они инициализируются — чуть ниже.

Вообще при работе с базой данных огромную роль помимо серверных настроек играют настройки клиент-серверного соединения (connection). На этом этапе вступают в игру следующие специфичные для соединения параметры:

  • character_set_client — кодировка в которой посылается запрос от клиента
  • character_set_connection — кодировка используемая для конвертации пришедшего запроса (statement’а)
  • character_set_results — кодировку, в которую сервер должен перевести результат перед его отправкой клиенту

Есть еще представление кодировки соединения ( colation_connection ). Для чего нужен этот параметр думаю пояснять не надо.

Озадачиваться проблемой инициализации всех этих переменных не стоит (хотя в нашем случае присвоить им значения необходимо). Есть способ проще: существует два типа запросов (statements) которые задают настройки соединения клиента с сервером группой:

Запрос SET NAMES ‘charset_name’ [COLLATE ‘collation_name’]

Параметр определяет в какой кодировке теперь будут приходить сообщения для сервера от клиента. Прелесть в том, что запрос SET NAMES x эквивалентен следующей группе:

SET character_set_client = x;
SET character_set_results = x;
SET character_set_connection = x;

Для определении представления кодировки соединения ( colation_connection ) отличного от дефолтного, следует дополнить запрос:

SET NAMES x COLLATE y

А так как у нас utf8 и ее дефолтное представление utf8_general_ci , то нам нужно выпонить полный запрос:

SET NAMES utf8 COLLATE utf8_unicode_ci

Таким образом, используя только этот запрос, можно добиться корректной UTF8 инициализации соединения.

Читайте также:  Imgburn как записать двд 9

Однако, тут есть один нюанс:

SET NAMES x , как понятно из определения, определяет настройку клиента при коннекте к серверу. Но что делать, если клиент — сам mysql.exe и нам хочется установить collation_connection по-умолчанию, не выполняя каждый раз SET NAMES x при коннекте?
Для этих целей, существует еще один параметр — default_character_set . Он эквивалентен запросу SET NAMES utf8 . В случае его использования задать collation_connection отличный от дефолтного уже не получится, поэтому придется заюзать еще одну команду init_connect (так как напрямую collation_connection нельзя прописать в конфигурационном файле):

init_connect=‘SET collation_connection = utf8_unicode_ci’

Но и тут есть еще одно но: init_connect команда не выполняется для SUPER пользователей — пользователей, обладающих привилегией SUPER. root входит в этот перечень, поэтому при коннекте root’ом команду SET collation_connection = utf8_unicode_ci все же придется выполнить вручную.

Запрос SET CHARACTER SET charset_name

Запрос групповой и он также эквивалентен следующей группе:

SET character_set_client = x;
SET character_set_results = x;
SET collation_connection = @@collation_database;

Согласно документации, разница между двумя запросами в том, что параметры character_set_connection и collation_connection будут установлены на @@character_set_database и @@collation_database соответственно (выше я про них упоминал).

За более детальной информацией отсылаю по двум источникам — собственно к официальной документации и прекрасно оформленному ответу на stackoverflow.com. Для нашей задачи вполне хватает первого параметра вместе с дополнительной командой.

Подытожим: различные сценарии и что юзается на каждом из них — относительно к настройкам соединения:

  • Если к базе коннектится mysql.exe клиент с пользователем с привилегией SUPER:
  • срабатывает опция в конфигурационном файле default_character_set = utf8
  • надо выполнить вручную команду init_connect=’SET collation_connection = utf8_unicode_ci’
  • Если к базе коннектится mysql.exe клиент с пользователем без привилегии SUPER:
    • срабатывает опция в конфигурационном файле default_character_set = utf8
    • срабатывает команда в конфигурационном файле init_connect=’SET collation_connection = utf8_unicode_ci’
    • Если к базе коннектится внешний клиент:
      • надо выполнить вручную команду SET NAMES utf8 COLLATE utf8_unicode_ci
      • Наши команды:
        my.cnf (my.ini)

        [client]
        default_character_set = utf8

        [mysqld]
        init_connect=‘SET collation_connection = utf8_unicode_ci’

        Кодировка (character set) и представление (collation) таблиц

        Тут все довольно просто. Задать кодировку и ее представление можно через команды:

        CREATE TABLE t1 ( … )
        CHARACTER SET utf8 COLLATE utf8_unicode_ci;

        Тут главное иметь в виду, что если эти настройки не заданы, то берутся настройки базы данных (см. пред. раздел). Нам эти настройки не интересны.

        Кодировка (character set) и представление (collation) колонок в таблице

        Тут по аналогии с пред. секцией. Если параметры кодировок не указаны, берутся те, что указывались для таблицы.

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

        skip-character-set-client-handshake

        Помимо освещенных параметров, есть еще один довольно часто фигурирующий в разного рода источниках — skip-character-set-client-handshake. Установка этого параметра позволит проигнорировать информацию клиента о кодировке. Я данный параметр не использовал.

        Верификация настроек

        Итак, вот финальный snapshot наших изменений в файле my.cnf (my.ini):

        [mysqld]
        init_connect=‘SET collation_connection = utf8_unicode_ci’
        character-set-server = utf8
        collation-server = utf8_unicode_ci

        [client]
        default-character-set = utf8

        После применения всех опций и рестарта сервера mysql для проверки настроек можно воспользоваться командами SHOW VARIABLES LIKE ‘char%’ и SHOW VARIABLES LIKE ‘collation%’ ;

        Состояние среды до изменений:

        Состояние среды после изменений (в случае, если вы приконнектились не SUPER пользователем):

        Для примера, вот отличие при соединении через mysql.exe пользователем с и без привилегии SUPER:

        с привилегией и выполненной вручную командой ‘SET collation_connection = utf8_unicode_ci’:

        Поздравляю, теперь ваши база, таблицы и все в таблицах по-умолчанию в кодировке UTF8.

        Добавить комментарий

        Ваш e-mail не будет опубликован. Обязательные поля помечены *