1. PHP использует неверную кодировку в качестве клиентской.
Симптомы:
Через phpMyAdmin (здесь и далее подразумевается версия умеющая работать с кодировками, т.е. >= 2.6.0) все по-русски, а в скрипт приходят вопросительные знаки.
Скрипт, заносящий данные в базу, видит русский нормально, а после вставки, как в правильном скрипте, так и в phpMyAdmin-е — знаки вопросов.
Тестирование:
Попробуйте в начале вашего скрипта, но после соединения, выполнить SQL-запрос "SET NAMES кодировка". Где кодировка - та кодировка, в которой у вас (по вашему мнению) данные. Например, для русской Windows кодировки (windows-1251) это будет cp1251, для KOI8-R – koi8r, для UTF-8 – utf8 и так далее. В дальнейшем она будет упоминаться как "кодировка".
Результат тестирования:
Если буквы (но необязательно слова) стали русскими, значит, данные в базе лежат в правильной кодировке, сама база эту самую кодировку и использует.
Если буквы стали русскими, а слова нет ("бнопня"), значит, скрипт ожидает данные в другой русской кодировке — пробуйте другие, пока не получится русских слов.
Решение:
1) Оставить запрос "SET NAMES кодировка" в начале скрипта. Если скриптов много – см. вариант 2.
2) Заставить MySQL автоматически выполнять этот запрос при каждом соединении с ним.
Для этого необходимо в конфигурационном файле MySQL, в секции [mysqld] добавить следующую строку: init-connect="SET NAMES кодировка".
Однако, следует заметить, что это НЕ будет работать, если пользователь, которым вы подключаетесь к базе имеет привилегию SUPER (а стандартный пользователь root к таким относится, так же как и все созданные через "GRANT ALL PRIVILEGES ON *.* TO ..."). Это сделано для того, чтобы в случае ошибки в этом запросе (а его можно изменить во время работы), хоть кто-то мог подключиться к базе и исправить его.
Внимание! Функция mysqli_client_encoding() и сотоварищи, отображает кодировку клиента на момент соединения и не меняют возвращаемое значение в процессе работы. Поэтому не стоит кричать, что кодировка не меняется. Просто делайте, что говорят и смотрите результат работы скрипта. Получить нужное значение можно SQL-запросом "SHOW VARIABLES LIKE 'character_set_client'".
3) Начиная с версий 4.1.15 и 5.0.13 добавить в секцию [mysqld] или [server] конфигурационного файла MySQL параметр skip-character-set-client-handsh ake. Этот параметр заставляет сервер игнорировать кодировку, посылаемую клиентом, и использовать указанную серверу. В примере конфигурации ниже этот параметр уже есть.
2. MySQL использует неверную кодировку
Симптомы:
Русский текст приходит в скрипт как русский, в консольном клиенте тоже все хорошо. Однако не работает сортировка, перевод в верхний/нижний регистр и т.д. Если применить решение из проблемы №1, то либо русский текст становится вопросами, либо mysql_error() возвращает сообщение похожее на "Illegal mix of collations (latin1_general_ci,IMPLICIT) and (cp1251_general_ci,COERCIBLE)...". В тоже время phpMyAdmin русский текст отображает как "крокозябры" (латинские символы с умляутами и т.д.).
Тестирование:
Попробуйте в phpMyAdmin'е выполнить запрос вида "SELECT CONVERT(CONVERT(поле USING binary) USING кодировка) FROM таблица". Где "таблица" и "поле" - соответствующая таблица и поле с русским текстом, а "кодировка" — кодировка из проблемы №1.
Результат тестирования:
Если буквы (но необязательно слова) стали русскими, значит текст в базе лежал не в правильной кодировке и его нужно сконвертировать.
Если буквы стали русскими, а слова нет ("бнопня"), значит неверно выбрана одна из русских кодировок – пробуйте другие, пока не получится русских слов.
Решение:
1) Установить для MySQL нужную кодировку по умолчанию.
Внимание! Это решение сработает сработает, только если кодировки не переопределены для базы, таблицы или столбца.
Для этого нужно в конфигурационном файле MySQL в секции [mysqld] добавить следующую строку:
default-character-set=cp1251
2) Сконвертировать таблицы в нужную кодировку.
Про то как конвертировать таблицы с неверными кодировками хорошо написано в мануале MySQL. Повторять здесь то же самое не к чему.
(Добавление)
Как сменить кодировку базы MySQL из командной строки
Допустим у нас есть база mysqldb, в неверной кодировке
по умолчанию. Мы хотим сменить ее в