php mysql set charset
mysql_set_charset
mysql_set_charset — Устанавливает кодировку клиента
Данный модуль устарел, начиная с версии PHP 5.5.0, и удалён в PHP 7.0.0. Используйте вместо него MySQLi или PDO_MySQL. Смотрите также инструкцию MySQL: выбор API. Альтернативы для данной функции:
Описание
Устанавливает кодировку по умолчанию для текущего соединения.
Список параметров
Корректное название кодировки.
Возвращаемые значения
Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.
Примечания
Данная функция требует MySQL версии 5.0.7 или выше.
Это наиболее предпочитаемый способ для смены кодировки. Использование mysql_query() в этих целях (например SET NAMES utf8 ) не рекомендуется. Смотрите раздел кодировка символов в MySQL для подробной информации.
Смотрите также
User Contributed Notes 8 notes
I needed to access the database from within one particular webhosting service. Pages are UTF-8 encoded and data received by forms should be inserted into database without changing the encoding. The database is also in UTF-8.
Neither SET character set ‘utf8’ or SET names ‘utf8’ worked properly here, so this workaround made sure all variables are set to utf-8.
?>
All important variables are now utf-8 and we can safely use INSERTs or SELECTs with mysql_escape_string($var) without any encoding functions.
Here’s an example of how to use this feature :
I wanted to store arabic characters as UTF8 in the database and as suggested in many of the google results, I tried using
mysql_query(«SET NAMES ‘utf8′»);
mysql_query(«SET CHARACTER SET utf8 «);
but it did not work.
Using the following, it worked flawlessly
$link = mysql_connect(‘localhost’, ‘user’, ‘password’);
mysql_set_charset(‘utf8’,$link);
Massage for nabeelmoidu at gmail dot com:
For me works following code:
I just hope that the text below will help someone who is struggling with charset encoding, specially when php-charset is different from the mysql-charset. Let me add that I really think that the php man-pages on the mysql-functions are lacking a lot of details on this important issues. Could someone add some useful text here?
Here is my situation. PHP5.2.4, MySql 4.1.15. A php web-application fully utf-8 encoded and a mysql database in latin1 charset.
To make this work I had to:
1. create and store all code files (php, html, inc, js, etc) in the utf-8 charset. Your editor should have an option for this, if not dump it.
2. check that your editor does not add a BOM (http://en.wikipedia.org/wiki/Byte-order_mark) at the beginning of the file. Use a hex-editor to detect them if needed.
4. Additionally add this meta-tag to your html-header: ‘ ‘. This will help silly browsers (Oeps, IE again?) that ignore the utf-response-header send to them.
5. Check that the above line are listened to by check the ‘page info’ of your pages in firefox. It should show 2 (!!) utf-8 entries.
======== all of the above sofar has nothing to do with mysql 😉 ======
6. Do *NOT* (repeat NOT!) set the ‘names’ (set names *) or _ANY_ ‘character set’ (set character set *) (opposed to what they tell you on these pages).
7. Check the previous item by listing the results of the mysql query ‘SHOW session VARIABLES’. All char_sets here should say ‘latin1’, except for the system one which is always ‘utf8’. All collations should say ‘latin1_*’. Furthermore the php function mysql_client_encoding() should also return latin1 (though I don’t understand why; what does this value mean, I would think if php (being the client) is utf8 encoded this would be utf8?)
8 Finally test the above by storing this string in your db and output it in your webpage: ‘Iñtërnâtiônàlizætiøn and €’.
Now what was interesting during testing and debugging of the above findings was:
1. If I would run ‘mysql_set_charset(‘utf8′)’ _OR_ ‘mysql_query(«SET NAMES ‘utf8′»);’ and then run a query in which I would have ‘where char_column = ‘abc»it would die with ‘Illegal mix of collations’
2. If I would run ‘mysql_query(«SET character_set_client = ‘utf8’;»); mysql_query(«SET character_set_result = ‘utf8′;»)’ the query would work BUT the non-ascii-characters would show scrambled in the browser.
3. BUT these 2 points above work just fine on my local dev-machine (php 5.2.3 & mysql 5.0.45).
This draws me to these 3 conclusions:
1. The Php-mysql-function library (5.2.+) does a fine job translating utf-8 queries & results to/from latin1! It’s better to let php handle this for you then to have mysql do this.
2. Mysql (4.0.+) has 1 or more bugs (well, let’s say unfinished features) that involve the charset-translations that are solved in 5.0.+.
3. It is not well enough documented! (Otherwise I would have to write this)
One last remark: clearly characters that exist in utf8 and not in latin1 (and vv.) will get lost during utf8-latin1-utf8 translation.
If any of the above is not correct or not complete feel free to correct this! (Or better yet, add a chapter to the php manual 🙂
mysqli::set_charset
(PHP 5 >= 5.0.5, PHP 7, PHP 8)
Описание
Задаёт набор символов, который будет использоваться при обмене данными с сервером баз данных.
Список параметров
Набор символов, который необходимо установить.
Возвращаемые значения
Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.
Примеры
Пример #1 Пример использования mysqli::set_charset()
Результат выполнения данных примеров:
Примечания
Чтобы использовать эту функцию на Windows платформах, вам потребуется клиентская библиотека MySQL версии 4.1.11 или выше (для MySQL 5.0 соответственно 5.0.6 или выше).
Это предпочтительный способ задания набора символов. Использование для этих целей функции mysqli_query() (например SET NAMES utf8 ) не рекомендуется. Дополнительно смотрите Наборы символов в MySQL.
Смотрите также
User Contributed Notes 5 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»);
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.
right before I did the SELECT command.
This is my code for reading from db :
$slct_stmnt = «SELECT «.$SELECT_WHAT.» FROM «.$WHICH_TBL.» WHERE «.$ON_WHAT_CONDITION;
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.
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:
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.
To align both the character set (e.g., utf8mb4) AND the collation sequence with the schema (database) settings:
Sergey Danielyan
Корректная настройка MySQL для работы с UTF8
Основная цель данного поста — выяснить, какие параметры и с какими значениями следует прописать в конфигурационный файл my.cnf (my.ini) для дальнейшей беспроблемной работы с Юникодом.
Рабочее окружение
UTF8 на данный момент у меня успешно работает в Мастер-Слейв конфигурации:
Любой внешний клиент в состоянии корректно работать с UTF8 базой (проверено на EMS Manager for MySQL c Windows 8 x64).
Все опции и настройки я привожу для версии сервера 5.1.x, однако с минимальными (а то и вовсе без оных) изменениями все это будет работать и на версиях 5.5.x и 5.6.x.
Параметры кодировок MySQL
Довольно часто приходится видеть в ответах на вопросы о настройке UTF8 следующее:
Предполагается, что после вставки всего этого добра (тут кстати есть противоречащие друг другу опции) в конфигурационный файл my.cnf (my.ini) магический Юникод начнет работать.
Но давайте забудем о списке и попытаемся разбираться со всеми опциями сами и начнем с самого начала. То есть с документации. Потому как все это прекрасно описано в документации MySQL на официальном сайте. Я лишь постараюсь последовательно рассказать о параметрах сервера и прояснить неясные моменты.
Символьная кодировка может быть задана для:
Сделано это для гибкой настройки баз данных и доступа клиентов с разными кодировками. Однако, последнее не входит в область рассмотрения данного поста, поэтому будем рассматривать вариант с кодировкой UTF8 настроенной для всего по-умолчанию.
Все параметры могут быть переданы серверу тремя разными способами:
Второй и третий варианты рассматриваться не будут. Тут уместно будет просто прочитать официальные доки — в каждом разделе приведены примеры конфигурации с использованием всех трех способов. Я же буду использовать первый вариант.
Кодировка (character set) и представление (collation) сервера
Тут есть несколько фундаментальных вещей которые надо понимать.
Можно задать оба параметра либо только один из них. При этом важно знать как задача того или иного влияет на определение отсутствующего:
SHOW COLLATION LIKE ‘your_character_set_name’;
Поле Default дает ответ о представлении выбранной кодировки.
В нашем случае, при настройке дефолтной кодировки в UTF8, параметры должны быть определены, так как могут быть использованы при определении кодировки или представления базы данных:
Наши команды:
my.cnf (my.ini)
[mysqld]
character-set-server = utf8
collation-server = utf8_unicode_ci
Кодировка (character set) и представление (collation) базы данных
Тут есть два варианта определения кодировки и представления:
явно — при выполнении запроса на создание базы данных:
CREATE DATABASE db_name CHARACTER SET latin1 COLLATE latin1_swedish_ci;
Вообще при работе с базой данных огромную роль помимо серверных настроек играют настройки клиент-серверного соединения (connection). На этом этапе вступают в игру следующие специфичные для соединения параметры:
Есть еще представление кодировки соединения ( 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
SET NAMES utf8 COLLATE utf8_unicode_ci
Таким образом, используя только этот запрос, можно добиться корректной UTF8 инициализации соединения.
Однако, тут есть один нюанс:
init_connect=‘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 соответственно (выше я про них упоминал).
Наши команды:
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
Верификация настроек
Итак, вот финальный 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.
SET NAMES utf8 in MySQL?
I often see something similar to this below in PHP scripts using MySQL
I have never had to do this for any project yet so I have a couple basic questions about it.
8 Answers 8
It is needed whenever you want to send data to the server having characters that cannot be represented in pure ASCII, like ‘ñ’ or ‘ö’.
That if the MySQL instance is not configured to expect UTF-8 encoding by default from client connections (many are, depending on your location and platform.)
Read Whether to use «SET NAMES» to see SET NAMES alternatives and what exactly is it about.
SET NAMES indicates what character set the client will use to send SQL statements to the server.
More elaborately, (and once again, gratuitously lifted from the manual):
SET NAMES indicates what character set the client will use to send SQL statements to the server. Thus, SET NAMES ‘cp1251’ tells the server, “future incoming messages from this client are in character set cp1251.” It also specifies the character set that the server should use for sending results back to the client. (For example, it indicates what character set to use for column values if you use a SELECT statement.)
The SQL command «SET CHARSET utf8» from PHP will ensure that the client side (PHP) will get the data in utf8, no matter how they are stored in the database. Of course, they need to be stored correctly first.
DDL definition vs. real data
Encoding defined for a table/column doesn’t really mean that the data are in that encoding. If you happened to have a table defined as utf8 but stored as differtent encoding, then MySQL will treat them as utf8 and you’re in trouble. Which means you have to fix this first.
What to check
You need to check in what encoding the data flow at each layer.
Conversion
I’m trying to store some data in a SQL Server database through php.
Problem is that special chars aren’t converted properly. My app’s charset is iso-8859-1 and the one used by the server is windows-1252.
Converting the data manually before inserting doesn’t help, there seems to be some conversion going on.
Running the SQL query ‘set char_convert off’ doesn’t help either.
Anyone have any idea how I can get this to work?
EDIT: I have tried ini_set(‘mssql.charset’, ‘windows-1252’); as well, but no result with that one either.
13 Answers 13
Client charset is necessary but not sufficient:
I searched for two days how to insert UTF-8 data (from web forms) into MSSQL 2008 through PHP. I read everywhere that you can’t, you need to convert to UCS2 first (like cypher’s solution recommends). On Windows SQLSRV said to be a good solution, which I couldn’t try, since I am developing on Mac OSX.
However, FreeTDS manual (what PHP mssql uses on OSX) says to add a letter «N» before the opening quote:
I had the same problem and ini_set(‘mssql.charset’, ‘utf-8’) did not work for me. However, it worked in uppercase:
I suggest looking at the following points:
If ini_set(‘mssql.charset’, ‘UTF-8’); doesn’t help AND you don’t have root access to modify the system wide freetds.conf file, here’s what you can do:
1. Set up /your/local/freetds.conf file:
2. Make sure your connection DSN is using the servername, not the IP:
3. Make FreeTDS to use your local freetds.conf file as an unprivileged user from php script via env variables:
It is not possible to avoid converting character sets when using TDS protocol version 7 or higher (roughly equivalent to MSSQL 2005 or newer).
I’ve had luck in a similar situation (using a PDO ODBD connection) using the following code to convert the encoding before printing output:
My data was also being stored in the database by another application, so I might be in a unique situation, although I hope it helps!
For me editing this file:
/etc/freetds/freetds.conf
. and changing/setting ‘tds version’ parameter to ‘7.0’ helped. Edit your freetds.conf and try to change this parameter for your server configuration (or global).
It will work even without apache restart.
In my case, It worked after I added the «CharacterSet» parameters into sqlsrv_connect() connection’s option.
I did not notice someone to mention another way of converting results from MSSQL database. The good old iconv() function: