TL;DR Почти без исключений проблема кроется в различных кодировках (charachter set) установленных в программе-клиенте (далее клиент) и в БД.
Если кодировки не совпадают, то после получения символьных данных из БД в клиенте производится неявная перекодировка этих данных из кодировки установленной в БД в кодировку установленную в клиенте. Неверно установленная кодировка в клиенте приведёт к неверному отображению символов.
Тоже самое действет для другого направления, т.е. для записи в БД.
Когда перекодировка в кириллицу возможна?
Если кодировка в клиенте является подмножеством кодировки в БД, т.е. все символы кодировки на клиенте содержаться в кодировке БД. Например, если в БД установлены:
-
US7ASCII
(только 7-ь бит),EE8MSWIN1250
илиEE8ISO8859P2
(восточноевропейские языки) и подобные им, то перекодировка невозможна. -
Многосимвольные кодировки:
AL32UTF8
,AL16UTF16
и т.п. — не должны вызывать проблем.
Как узнать, какая кодировка установлена в БД?
select value
from nls_database_parameters
where parameter = upper ('nls_characterset');
Как установить нужную кодировку в клиенте?
Зависит собственно от клиента, но в большинстве случаев, т.к. используют одни и те же библиотеки доступа к БД (OCI, JDBC), действуют установки в следующей последовательности (последовательность важна, из нескольких последняя выиграет):
-
(Только Windows) в реестре:
HKLMSOFTWAREORACLEKEY_[Client_home1]: NLS_LANG=.CL8MSWIN1251
-
В переменной окружения
NLS_LANG
-
WIN:
Свойствa системы -> Дополнительно -> Переменные среды
или в командном интерпретере:set NLS_LANG=.CL8MSWIN1251
-
UNIX:
~/.profile
или в терминале:export NLS_LANG=.CL8MSWIN1251
-
-
Программа-клиент может иметь свои собственные установки, которые перепишут все выше описанные.
Значение NLS_LANG
состоит из 3-х независимых друг-от-друга частей и имеет форму: language_territory.characterset
, например NLS_LANG = AMERICAN_RUSSIA.CL8MSWIN1251
.
В данной теме интересна последняя часть после точки.
Кодировка в клиенте установлена правильно, но увы, куда смотреть дальше?
-
В программе или терминале не установлена поддержка кириллических символов.
- WIN: в командном интерпретере вывод
chcp
совпадает с желаемой кодировкой?
Попробуйте изменить, например:chcp 1251
- UNIX: проверте переменную окружения:
env | grep LANG
-
В программе могут быть специальные установки для поддержки различных кодировок, например в SQL Developer:
Preferences -> (+) Environment -> Encoding: [ ... ]
- WIN: в командном интерпретере вывод
-
Установленный шрифт не поддерживает кириллические символы. Попробуйте заменить шрифт по-умолчанию.
-
Кодировка в клиенте изменнена после того, как с предедущей кодировкой были произведены операци изменения (или вставки). Все измененые в БД данные, содержащие кириллические символы — «мусор». Удалите изменения и повторите их после установки правильной кодировки в клиенте.
Подробнее в офф. документации.
Битые символы в базе данных образуются, в большинстве случаев, из-за несовпадения кодировок в файле источнике, клиенте БД или таблице БД. Пройдемся по проблемным местам, один из пунктов ниже обычно помогает решать проблемы с «кракозябрями».
1. Файл-источник данных.
С этим пунктом все просто, текстовые данные в файле нужно хранить в utf8. Проверить кодировку можно в большинстве популярных IDE, например, в PhpStorm или текстовом редакторе наподобие Notepad++.
Если нет прямого доступа к БД, то в файл-источник данных следует прописать:
SET NAMES 'utf8' COLLATE 'utf8_general_ci'; -- Для utf8
или
SET NAMES 'utf8mb4' COLLATE 'utf8mb4_general_ci'; -- Для utf8mb4
2. Кодировка и формат сопоставления данных в таблице.
Вероятнее всего вы используете utf8 (он же utf8mb3) или utf8mb4 для хранения данных в MySql. Поэтому при создании таблиц желательно напрямую указывать это, т.к. не всегда общие настройки БД разрешается менять.
Для utf8:
CREATE TABLE `example_table` ( id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, example_field VARCHAR(255) NOT NULL ) CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB;
Для utf8mb4:
CREATE TABLE `example_table` ( id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, example_field VARCHAR(255) NOT NULL ) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE=InnoDB;
3. Импорт данных из файла-источника.
При импорте тоже желательно указывать кодировку.
Для utf8:
mysql -u USER_NAME -p --default-character-set=utf8 DB_NAME < SOURCE_FILE.sql
Для utf8mb4:
mysql -u USER_NAME -p --default-character-set=utf8mb4 DB_NAME < SOURCE_FILE.sql
4. Веб-интерфейсы.
Иногда требуется заполнять БД из веб-интерфейсов и в этом случае стоит проверять отправляемую кодировку с сервера в заголовках и HTML-коде.
HTML:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
PHP:
header('Content-Type: text/html; charset=utf-8');
Полезные команды
Отображение форматов сопоставления данных в MySql:
SHOW VARIABLES LIKE 'collation%';
Отображение настроек кодировок:
SHOW VARIABLES LIKE 'character%';
За последние 24 часа нас посетили 10906 программистов и 1190 роботов. Сейчас ищут 610 программистов …
Проблема с кодировкой. Вместо русских букв кракозябры.
Тема в разделе «MySQL», создана пользователем Sergey89, 30 янв 2008.
Страница 1 из 3
-
Sergey89
Активный пользователь- С нами с:
- 4 янв 2007
- Сообщения:
- 4.796
- Симпатии:
- 0
Данная «проблема» ждёт пользователей MySQL версии 4.1 и выше, которые никогда не пытались читать документацию.
Первым делом нужно проверить, что установлено нужное сопоставление (collation) для текстовых полей в таблице. Именно в установленной кодировке хранятся данные. Если для полей выставлена «неправильная» кодировка, то измените её. В phpMyAdmin это можно сделать при редактировании столбца таблицы, выбрав нужное значение из списка Сравнений. Для русский символов это может быть, например, cp1251_general_ci (основная регистронезависимая cp1251). Для UTF-8 — utf8_general_ci.
Теперь нужно выставить кодировку соединения с сервером. В MySQL есть выражение SET NAMES, предназначенное специально для этого:
[sql]SET NAMES ‘cp1251’;[/sql]
Выполнить данный запрос нужно сразу после подключения к серверу.После этого все данные будут приходить в установленной кодировке. Кодировку соединения можно менять:
[sql]SET NAMES ‘utf8’;[/sql]
В этом случае данные будут приходить в UTF-8, никак не затрагивая данные в таблице, которые могут храниться в другой кодировке. Следите за тем, чтобы весь остальной текст на странице тоже был в UTF-8.Вопросы? Замечания?
-
M@rko
Активный пользователь- С нами с:
- 21 янв 2008
- Сообщения:
- 5
- Симпатии:
- 0
пробовал.
все равно ведает кроказяблы! хоть и другие… -
Sergey89
Активный пользователь- С нами с:
- 4 янв 2007
- Сообщения:
- 4.796
- Симпатии:
- 0
Предлагаешь мне погадать? В какой кодировке таблица, в какой кодировке страница? Юзер рутовый или нет?
-
Команда форума
МодераторДобавлю к сообщения Сергея:
Сегодня была фигня, что русский текст показывался корректно (utf8 и в БД и на странице), но буквы «ш» и «И» показываются в виде квадратиков (в IE) и другими крякозябрами в других браузерах. Погуглив, решил проблему так:На БД и таблицы установил utf8_general_ci
После коннекта к БД:
[sql]
mysql_query(«SET NAMES ‘utf8’;»);
mysql_query(«SET CHARACTER SET ‘utf8’;»);
mysql_query(«SET SESSION collation_connection = ‘utf8_general_ci’;»);
[/sql]И все нормально работает.
-
tmanager
Активный пользователь- С нами с:
- 12 мар 2008
- Сообщения:
- 108
- Симпатии:
- 0
Стоит добавить, как поддержка кодировки уcтанавливается на MySQL под Windows
Пример конфигурационного файла my.ini
[client]
port = 3306#Конфигурационные параметры для сервера MySQL
[mysqld]
port = 3306
socket = /tmp/mysql.sock
skip-locking
key_buffer = 16K
max_allowed_packet = 1M
table_cache = 4
sort_buffer_size = 64K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 64K
# Установка кириллицы на сервере
default-character-set=cp1251 #Указание кодировки
character-sets-dir=g:/mysql/share/charsets #Указание пути к папке кодировок (скорректируйте для своего сервера!)server-id = 1
# Конфигурационные параметры для программы резервного копирования
[mysqldump]
quick
max_allowed_packet = 16M
# Установка кириллицы
default-character-set=cp1251 #Указание кодировки
character-sets-dir=g:/mysql/share/charsets #Указание пути к папке кодировок (скорректируйте для своего сервера!)# Конфигурационные параметры для программы-клиента mysql.exe
[mysql]
no-auto-rehash
# Установка кириллицы
default-character-set=cp1251 #Указание кодировки
character-sets-dir=g:/mysql/share/charsets #Указание пути к папке кодировок (скорректируйте для своего сервера!)[isamchk]
key_buffer = 8M
sort_buffer_size = 8M[myisamchk]
key_buffer = 8M
sort_buffer_size = 8M[mysqlhotcopy]
interactive-timeout -
Astoret
Активный пользователь- С нами с:
- 28 фев 2008
- Сообщения:
- 9
- Симпатии:
- 0
Спасибо Sergey89, очень помог твой пост. Двое суток бился, иска))
-
Astoret
Вот этот? -
Astoret
Активный пользователь- С нами с:
- 28 фев 2008
- Сообщения:
- 9
- Симпатии:
- 0
-
EugeneTM
Активный пользователь- С нами с:
- 19 апр 2008
- Сообщения:
- 85
- Симпатии:
- 0
Возможно окончательная победа в войне с utf8
MySQL
my.cnf или под виндой my.ini:[client]
default-character-set= utf8
[mysql]
default-character-set=utf8
[mysqld]
default-character-set=utf8
В PHP-скрипте
<?php
/* create a connection object which is not connected */
$link = mysqli_init();
/* connect to server */
mysqli_real_connect($link, ‘localhost’, ‘root’, ‘бла-бла-бла’, ‘бла’);/* check connection */
if (mysqli_connect_errno()) {
printf(«Ошибка соединения с БД : %sn», mysqli_connect_error());
exit();
}/* Устанавливаем кодировку для корректного вывода в браузере */
$query = «SET NAMES ‘utf8′»;
if (mysqli_query($link,$query) === TRUE) {
printf(«Кодировка UTF8 успешно установлена.n»);
}
else {
printf(«Ошибка выполнения запроса на установку кодировки UTF8 для вывода в браузере : %sn»,
mysqli_error($link));
exit ();
}/* Устанавливаем кодировку для корректного collation*/
$query = «SET SESSION collation_connection = ‘utf8_general_ci’;»);
if (mysqli_query($link,$query) === TRUE) {
printf(«Collation UTF8 успешно установлен.n»);
}
else {
printf(«Ошибка выполнения запроса на установку collation UTF8 : %sn»,
mysqli_error($link));
exit ();
}/* close connection */
mysqli_close($link);
?>
Если используете библитеку mysql, соотвтственно подкорректировать вызываемые функции.!!!!! Сам PHP-скрипт должен быть в кодировке UTF8
!!!!! Скрипты MySQL должны быть в кодировке UTF8. Для танкистов: Если в notepad создать текстовый файл, набить какой нибудь код. Этот файл будет иметь кодировку cp1251. Если он будет содержать русские символы, то при попытке выполнить его из под mysql будете посланы на ERROR. Один из примитивных вариантов: в MySQL Query Browser создайте новый Script Tab. В него из Clipboard’а вставте ваш текст. Сохраните его как superpuper.SQL, сравните размер с исходным текстовым файлом. Этот скрипт будет нормально выполняться из под mysql при наличии в нем русских символов. Аналогично проверьте PHP-скрипт.
!!!!! Вставка из clipboarda винды в командную строку mysql катит только если текст не содержит русских символов. Винда вставляет cp1251, и соответственноо mysql посылает на ERROR.
Если все это выполнено, нигде никаких упоминаний про cp1251 не нужно.
PS. Имейте в виду — размер VARCHAR при использовании utf8 не должен превышать 64К/3 = 21,33К
-
Не думал, что после того чего уже пережил — напишу сюда, но
Винда, кодировки в базах — юникод, на страничках — utf8, то же и скрипты.
Не пугайтесь, со страничками все хорошо, везде все по русски. Но, решил сегодня воспользоваться консолью мускуловской, не тут то было: ╨Э╨░╤З╨░╤В╨░ вот такие бяки. И сет намес ставил..
Мне кажется что просто сама консоль 1251 по этому и такие карявости. Я не прав? в любом случае, как это победить, или лучше не париться и юзать как раньше майадмин? -
Sergey89
Активный пользователь- С нами с:
- 4 янв 2007
- Сообщения:
- 4.796
- Симпатии:
- 0
-
У меня программа, в которой я php-код редактирую, иногда возмёт да и сохранит файл в однобайтовой кодировке.
Она это может делать автоматически, если все символы в документе принадлежат одной однобайтовой кодировке и нет ни одного символа из другой.Чтобы быть уверенным, вставляю в начало документа комментарий: #юертз ěščřž
Т.е. набор из символов, которые могут быть одновременно только в многобайтовой кодировке.В notpade тоже можно сохранить в utf-8, если при сохранении в окне её выбрать.
-
Помогите мне пожалуйста…. :_(
Пользуюсь консольным клиентом.
Я создал БД:[sql]CREATE DATABASE admins DEFAULT CHARACTER SET cp1251 COLLATE cp1251_general_ci[/sql]
Создал таблицу, внес в нее данные и между каждым действием писал[sql] set names c1251;[/sql]
На самой странице написал:-
<meta http-equiv=Content-Type content=«text/html; charset=windows-1251» />
И всеравно пишутся каракули *WALL*
-
-
тоже из консоли?
У консоли кодировка cp866 -
- С нами с:
- 2 фев 2007
- Сообщения:
- 4.680
- Симпатии:
- 1
- Адрес:
- Минск
вот скажите мне, ну, есть консоль, ну есть шелл-доступ, и что? Теперь только этим и пользоваться? А вот я ленивый и в консоль лезу только в случаях, когда это действительно надо. Люблю тыкать в кнопки и ссылки
LokiFC
set names c1251; достаточно 1 раз прописать. После соединения с бд.
И вполене возможно, что данные твои пишутся нормально. Попробуй отсешь другие варианты.
В какой кодировке сохранён сам файл? Сомневаюсь, что utf-8, но а вдруг?
Потом, в апаче есть такая директива, как AddDefaultCharset. Отвечает за кодировку в которой по умолчанию будут отдаваться серваком файлы. И если стоит utf-8 или другая отличная от WINDOWS-1251, то чихал он на-
<meta http-equiv=Content-Type content=«text/html; charset=windows-1251» />
. Лечится либу правкой конфига апача, либо отправкой перед выводом текста заголовка
-
<? header(‘Content-Type: text/html; charset=CP1251’); ?>
Вот будешь уверен, что таких косяков нет, можно будет гнать на БД и сочинять всякие извращённые способы заполнения.
-
Sergey89
Активный пользователь- С нами с:
- 4 янв 2007
- Сообщения:
- 4.796
- Симпатии:
- 0
Набери в консоли или обрати внимание на то, что
-
2Luge, помогло
Не думал, что проблема может заключатся в неправильном способе задачи кодировке странице…
…а это было так…. -
Madkin
Активный пользователь- С нами с:
- 23 янв 2008
- Сообщения:
- 18
- Симпатии:
- 0
Доброго времени суток!
Мужики, что я делаю не так?
Ситуевина следующая:
1. База, таблица, записи в кодировке cp1251
2. Страница в кодировке cp1251
3. На странице даже вставлен mysql_query(«SET NAMES ‘cp1251′»);В итоге страница вылезает в кодировке cp1251(как и задумывалось), данные из мускуля на странице отображаются знаками вопроса(что нежелательно). (((
-
- С нами с:
- 8 апр 2007
- Сообщения:
- 5.433
- Симпатии:
- 0
Может сервер высылает заголовок http в другой кодировке?
Попробуйте header(«Content-type: text/html; charset=windows-1251»); -
Madkin
Активный пользователь- С нами с:
- 23 янв 2008
- Сообщения:
- 18
- Симпатии:
- 0
Ну я так понимаю, что изменив в апаче AddDefaultCharset UTF-8 на CP-1251, я вроде бы как сделал тоже самое.
К сожалению проблема осталась (((.
Есть ли смысл дефолтовой кодировкой мускуля сделать CP-1251? Сейчас в мускуле повсюду юникод — созданное мной как белая ворона в виндовой кодировке лежит.
-
Madkin
Активный пользователь- С нами с:
- 23 янв 2008
- Сообщения:
- 18
- Симпатии:
- 0
Еще раз, здравствуйте!
Продолжаю мучение:
Выставил дефолтовую кодировку для mysql в cp1251 — результат от же ((((
Может кто-нить подбросит совет? вот что имею:
1. Апаче раздает страницы с параметром AddDefaultCharset CP-1251
2. Мускуль в настройках my.cnf раздел [mysqld] (может тут беда?) имеет 2 параметра
— collation_server = cp1251_general_ci
— character_set_server = cp1251
3. База, таблицы в базе, записи в таблицах в в cp12-51_general_ci
4. Страница в windows-1251
5. Страница имеет mysql_query(«SET NAMES ‘cp1251′»);Со всем этим у меня трабла — все что вытягивается из мускуля — на странице превращается в знаки вопроса.
УПД.
Загугли решают )) Правильно поставленный поисковый вопрос — 80% сделано
Добавил следующее после коннекта с базой — заработало-
mysql_query («set collation_connection=’cp1251_general_ci'»);
Спамибо ответившим.
-
ZMANZ
Активный пользователь- С нами с:
- 10 мар 2008
- Сообщения:
- 161
- Симпатии:
- 0
Здраствуйте!!!
При добавлении информации через блок администратора в базу данных mysql, в базе данных информация отображается иероглифами, но только когда печатаешь русскими буквами!!! При отправке формы английскими или цифрами приходит все нормально!!! Страница с которой происходит отправка имеет кодировку utf8!!! phpMyAdmin 2.6.1, MySQL 4.1.16, Appach 1.3.33 Php 5.1.2!!!
Где и что нужно поменять, чтоб небыло этих иероглифов??? Как я понял идет именно несовместимость кодировок страница в utf8, а mysql 1251!!! А так все отображаеца нормально, проблема именно при поступлении данных в базу, приходят ИЕРОГЛИФЫ!!! -
- С нами с:
- 2 фев 2007
- Сообщения:
- 4.680
- Симпатии:
- 1
- Адрес:
- Минск
привычку не читать первое же сообщение в теме.
Страница 1 из 3
Здравствуйте .. Не хотел создавать новую тему, так как есть уже эта.. Почитал похожие темы, нечего не помогло..
Есть у меня база БД MySQL
Есть страница вывода запроса к БД на PHP
Решил сделать все под utf8
БД находится в UTF8, прописал в htaccess
CharsetDefault utf-8
CharsetSourceEnc utf-8
AddDefaultCharset utf-8
Страницу вывода изменил на UTF
В странице, результат запроса выводится в select (каскадный список). Так вот этот список в «???????».
Когда выбираю в браузере windows-1251 то все наоборот, список норма, страница в кровозябрах.
Выходит что данные почему то в windows-1251
Данные сервера
character_set_client utf8
character_set_connection utf8
character_set_database utf8
character_set_filesystem binary
character_set_results utf8
character_set_server cp1251
character_set_system utf8
character_sets_dir /usr/share/mysql/charsets/
Создаю таблицу так
CREATE TABLE grh_country (
itemid_country INT NOT NULL ,
name_country varchar(20) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Ввод данных делаю через майадмин
INSERT INTO grh_country (itemid_country,name_country)
VALUES
(’01’,’Андорра’),
(’02’,’Объединенные Арабские Эмираты’),
(’03’,’Антигуа и Барбуда’),
(’04’,’Ангилья’),
(’05’,’Албания’),
(’06’,’Армения’),
(’07’,’Антильские Острова’),
(’08’,’Ангола’),
(’09’,’Антарктика’),
(’10’,’Аргентина’),
(’11’,’Американское Самоа’),
(’12’,’Австрия’);
Выборку делаю скриптом PHP
$name_count = mysql_query(«select * FROM grh_country ORDER BY name_country «);
Даже если делать так, тоже без толку
mysql_query («set character_set_client=’utf8′»);
mysql_query («set character_set_results=’utf8′»);
mysql_query («set collation_connection=’utf8′»);
«SET NAMES UTF8». — тоже не помогает…
Подскажите плиз, а то уже неделю лбом бьюсь …
Заранее благодарен!!
Решено! Проблема была в чрезмерной экономии хостинг провайдера. А именно в мизерных настройках MySQL.
Их можно отобразить SQL командой:
Во-первых, кодировка по умолчанию на хостинге стоит cp1251, которую нельзя поменять.
Во-вторых, параметр wait_timeout был равен 15! Это значит, что если между SQL запросами бальше 15 секунд, то текущее MySQL соединение закрывается, а когда делаешь следующий запрос, соединение создаётся снова, но уже с кодировкой по умолчанию!
Это решается либо просьбой хостера поднять этот параметр до вменяемого значения, либо можно сделать это самому командой:
SQL | ||
|
P.S. Ох уж эти хостинги…