Кодировки и пользователи в MySQL

На примере установки PHP-Nuke

Захотел я установить себе движок PHP-Nuke. Много я слышал, про то, что это один из самых дырявых, если не самый :), но это меня не смутило, т.к. я знаю сайты, которые долго и успешно работают на этом движке, с другой стороны, известно множество сайтов не на PHP-Nuke, которые, тем не менее, были сломаны.
Лично мне PHP-Nuke понравился. Смотрел я еще Drupal, который сейчас пользуется популярностью, но что-то меня он не впечатлил.
Но при чем тут кодировки и пользователи MySQL? А при том, что столкнулся я с некоторыми проблемами при установке БД движка, и их решение покажу здесь.
Итак, имеем сервер FreeBSD 6.1 с установленной MySQL 5.1
С официального сайта качаю английскую версию PHP-Nuke 7.8
В дистрибутиве краткая инструкция по установке. Про создание базы данных там всего 2 пункта:
1) Create a database called, for example, nuke:
    mysqladmin create nuke 
2) Now fill the databases with the tables in nuke.sql file:
    mysql nuke < nuke.sql
          
Все просто. Какие проблемы?
А проблемы классические для русскоязычных пользователей - кодировки. Попробуем посмотреть, какие кодировки поддерживает наша СУБД по умолчанию:
        
mysql> show variables like "char%";                             
+--------------------------+----------------------------------+ 
| Variable_name            | Value                            | 
+--------------------------+----------------------------------+ 
| character_set_client     | latin1                           | 
| character_set_connection | latin1                           | 
| character_set_database   | latin1                           | 
| character_set_filesystem | binary                           | 
| character_set_results    | latin1                           | 
| character_set_server     | latin1                           | 
| character_set_system     | utf8                             | 
| character_sets_dir       | /usr/local/share/mysql/charsets/ | 
+--------------------------+----------------------------------+


Надеюсь, вы работаете в командной строке? Вы же не ламерюга, который только в окошках и ориентируется? :) Если вы не поняли, что изображано на картинке и откуда это взялось, то на этом можно и прекращать чтение данной статьи. :)
Итак, что-то ничего похожего на виндовую кодировку не видно.
Ладно, пробуем создать какую-нибудь тестовую статью. Вот что получилось:



Вместо вопросительных знаков должен быть русский текст.
Попробуем во время создания БД сразу указать кодировку. Сначала убиваем старую БД:
 # mysqladmin drop nuke  


Теперь создаем новую, с нужной кодировкой.
mysql> create database nuke default character set cp1251 collate cp1251_general 
_ci;                                                                            
Query OK, 1 row affected (0.00 sec)                                             


Заливаю данные, добавляю новую статью и снова вижу одни вопросительные знаки.
Дело в том, что одной только кодировки БД не достаточно, кодировка клиента тоже должна быть соответствующей.
Поск в Интернете дает ответ, что для установки виндовой кодировки у сервера и у клиента нужно добавить следующие строки в конфигурационный файл MySQL my.cnf:
[mysqld]  
init-connect="SET NAMES cp1251"      
character_set_server = cp1251        
collation_server = cp1251_general_ci 
skip-character-set-client-handshake 
Добавляю, перезагружаю сервер MySQL, проверяю:

mysql> show variables like "char%";                              
+--------------------------+----------------------------------+  
| Variable_name            | Value                            |  
+--------------------------+----------------------------------+  
| character_set_client     | cp1251                           |  
| character_set_connection | cp1251                           |  
| character_set_database   | cp1251                           |  
| character_set_filesystem | binary                           |  
| character_set_results    | cp1251                           |  
| character_set_server     | cp1251                           |  
| character_set_system     | utf8                             |  
| character_sets_dir       | /usr/local/share/mysql/charsets/ |  
+--------------------------+----------------------------------+  


Ура, подействовало! Все кодировки - какие и нужно.
Проверяю на PHP-Nuke, добавляю новую статью - русские буквы отображаются!

PHP-Nuke, статья отображается нормально

Вот мы и подошли к пользователя. Когда я искал информацию о кодировках, то в некоторых местах читал, что после измениния файла my.cnf клиентское соединение будет в нужной кодировке только тогда, когда пользователь не root. Но у меня все работает и при root'e.
Все дело в строчке skip-character-set-client-handshake, если ее нет, то пользователь root соединяется c кодировкой latin1, а если она присутсвует, то и у root'a будет кодировка cp1251.
Но, в любом случае, под рутом работать не рекомендуется из соображений безопасности.
Поэтому я решил создать пользователя специально для БД nuke. Создавать будем штатно, т.е. не используя прямую вставку в служебные таблицы, а используя специально для этого предназначенные операторы MySQL. Справку об этих ператорах можно получить с помощью команды help account management

mysql> help account management           
You asked for help about help category: "Account Management"        
For more information, type 'help ', where  is one of the following
topics:                
   CREATE USER    
   DROP USER     
   GRANT 
   RENAME USER
   REVOKE
   SET PASSWORD



Справку можно получить и о каждом из этих операторов, например help create user

Создаем пользователя с именем user1:
mysql> create user user1;            
Query OK, 0 rows affected (0.01 sec) 



Создаем для него пароль:
mysql> set password for user1 = password('111');
Query OK, 0 rows affected (0.03 sec)             



Даем ему права на БД nuke:
mysql> grant all on nuke.* to user1; 
Query OK, 0 rows affected (0.04 sec)              



Ну, вроде, все ОК, пробуем соединится:
# mysql nuke -u user1 -p111       
ERROR 1045 (28000): Access denied for user 'user1'@'localhost' (using password:
YES)        



Не получается :(
А если указать этого пользователя в конфигурационном файле PHP-Nuke, то увидим следующее:


Причина в том, что для локального входа, т.е. когда пользователь и БД находятся на одном компьютере, при указании имени пользователя нужно явно указать, что это локальный пользователь. Делается это с помощью слова localhost. Повторим процедуру, с учетом этого:
mysql> create user user2@localhost; 
Query OK, 0 rows affected (0.01 sec)   
                                                 
mysql> set password for user2@localhost = password('222');
Query OK, 0 rows affected (0.00 sec)       
                               
mysql> grant all on nuke.* to user2@localhost;  
Query OK, 0 rows affected (0.00 sec)          



Пользователь user2 добавлен, пробую присоединиться к БД:
# mysql nuke -u user2 -p222    
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 24 to server version: 5.1.6-alpha
                     
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
                             
mysql>            



Все получилось! Обратите внимание, что при подключении к БД слово localhost можно не указывать. Теперь добавляем нашего пользователя в конфигурационный файл PHP-Nuke config.php
                     
$dbhost = "localhost";
$dbuname = "user2";. 
$dbpass = "222";



Работает!
Все, мы не только разобрались с пользователями и кодировками, но и стали обладаелеми собственного информационного портала!

TopList Rambler's Top100