За последние 24 часа нас посетили 53850 программистов и 1715 роботов. Сейчас ищут 928 программистов ...

Кодировка MySQL

Тема в разделе "Прочие вопросы по PHP", создана пользователем DeadMoroz, 15 июл 2013.

  1. DeadMoroz

    DeadMoroz Новичок

    С нами с:
    27 июн 2013
    Сообщения:
    18
    Симпатии:
    0
    Всем привет! Имеется в php-сценарии такой запрос:
    mysql_query("INSERT INTO users(firstName, lastName, email) VALUES ('{$first_name}', '{$last_name}', '{$email}');");
    кодировка переменных - utf-8 (проверял с помощью mb_detect_encoding())
    кодировка в базе:
    character_set_client utf8
    character_set_connection utf8
    character_set_database utf8
    character_set_filesystem binary
    character_set_results utf8
    character_set_server utf8
    character_set_system utf8
    character_sets_dir /usr/local/share/mysql/charsets/

    Вроде совпадает. Но! Если в запросе переменные содержат русскоязычный текст, в таблицу записываются пустые значения (с латиницей все ок). В чем тут может быть хитрость? Спасибо!

    Добавлено спустя 29 минут 5 секунд:
    есть еще такой нюанс
    если добавить в сценарий строку
    header("Content-Type: text/html; charset=utf-8");
    и попробовать вывести запрос с помощью echo, русские буквы заменяются на '?'.
    А если header("Content-Type: text/html; charset=windows-1251");, то echo выводит сам запрос корректно
    Может, браузер как-то меняет кодировку символов, прежде чем отправить строку на сервер? Как это проверить-исправить?
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    браузер посылает в той, в которой страницу опознал. соотв посмотри что он об этом думает.
     
  3. uorypm

    uorypm Активный пользователь

    С нами с:
    3 мар 2012
    Сообщения:
    98
    Симпатии:
    0
    В какой кодировке сохранен файл скрипта?
     
  4. DeadMoroz

    DeadMoroz Новичок

    С нами с:
    27 июн 2013
    Сообщения:
    18
    Симпатии:
    0
    1) браузер считает кодировку "Кириллица (Windows)"
    несмотря на то, что в сценарии есть строка header("Content-Type: text/html; charset=utf-8");
    если в самом браузере сменить кодировку на utf-8, то echo строки запроса выглядит так:
    INSERT INTO users(firstName, lastName, email) VALUES ('���', '�������', [email='email@email.ru]'email@email.ru[/email]');
    2) в какой кодировке сохранен файл сприпта - не знаю, как определить это. Скрипт хранится на сервере провайдера, я редактирую его в окне какого-то встроенного примитивного редактора там же, на серваке
    Значения переменных скрипт получает из веб-формы (через ;$_REQUEST), т.е. по идее в php значения отправляет браузер. mb_detect_encoding говорит, что эти значения получены в utf-8. Сам скрипт браузер не задействует, он просто получает переменные из веб-формы и сохраняет их в базе данных. Т.е. браузер к сохранению значений в базе по идее не должен иметь отношения?
     
  5. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    добейся чтобы везде была одна кодировка
     
  6. DeadMoroz

    DeadMoroz Новичок

    С нами с:
    27 июн 2013
    Сообщения:
    18
    Симпатии:
    0
    честно говоря, даже не знаю, где еще эту кодировку ловить. Скрипт получает значения из формы html в utf-8, передает значения базе, у которой кодировка utf-8... ((
     
  7. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    разберись с этим. видимо твой header() не работает потому что раньше него есть какой-то вывод.
    к базе не лезь, пока это не исправишь. не накладывай одну попаболь на другую.
     
  8. DeadMoroz

    DeadMoroz Новичок

    С нами с:
    27 июн 2013
    Сообщения:
    18
    Симпатии:
    0
    а я как раз полез в базу (
    сменил кодировку таблицы users (в которую пишем данные) с utf-8 на windows-1251
    скрпит выглядит так:
    $first_name = trim( $_REQUEST['first_name']);
    $last_name = trim($_REQUEST['last_name']);
    $email = trim($_REQUEST['email']);

    $insert_sql = "INSERT INTO users(firstName, lastName, email) VALUES ('{$first_name}', '{$last_name}', '{$email}');";
    $insert_sql = iconv('windows-1251', 'UTF-8', $insert_sql);
    echo mb_detect_encoding($insert_sql);
    mysql_query($insert_sql) or die(mysql_error());
    теперь в базу вставляются правильные (русскоязычные) значения. Без iconv не вставляются.
    забавно, что эхо упрямо показывает, будто запрос закодирован в utf-8 (хотя же вот запускается предварительно iconv()...
    если в таблицу windows-1251 вставляются нормальные буквы, значит и запрос в этой кодировке поступает в базу? тогда не понятно, почему mb_detect_encoding определяет кодировку как utf-8. И осталось непонятным, почему не получалось в utf-8 вставлять значения в таблицу с кодировкой utf-8.
     
  9. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    ты читать умеешь?
     
  10. DeadMoroz

    DeadMoroz Новичок

    С нами с:
    27 июн 2013
    Сообщения:
    18
    Симпатии:
    0
    читать нет, только писАть )
    если серьезно, сорри, что не ответил на ремарку - сейчас (после перекодировки таблицы в windows-1251) сценарий выглядит так:
    <?php
    require '../../scripts/database_connection.php';
    header("Content-Type: text/html; charset=windows-1251");
    $first_name = trim( $_REQUEST['first_name']);
    $last_name = trim($_REQUEST['last_name']);
    $email = trim($_REQUEST['email']);

    $insert_sql = "INSERT INTO users(firstName, lastName, email) VALUES ('{$first_name}', '{$last_name}', '{$email}');";
    //$insert_sql = iconv('windows-1251', 'UTF-8', $insert_sql);
    echo mb_detect_encoding($insert_sql);
    mysql_query($insert_sql) or die(mysql_error());
    ?>
    Перед header нет никаких выводов. И вот это header не работает, т.е. в базу русские буквы не пишутся.
    Если раскомментировать строку с iconv(), то все пишется нормально. Стало быть, header тут как мертвому припарка.
    Если вставить в форму, которая отправляет переменные, строку <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">, тоже ничего не меняется (т.е. переменные не записываются корректно в таблицу с кодировкой windows-1251).
     
  11. uorypm

    uorypm Активный пользователь

    С нами с:
    3 мар 2012
    Сообщения:
    98
    Симпатии:
    0
    DeadMoroz, попробуй вернуть все как было и в скрипте сразу же после создания подключения выполни код
    Код (PHP):
    1. <?php
    2. // ...
    3. mysql_query("SET NAMES utf8");
    4. // ...
    5.  
    6.  
    И выполни чтение из базы.
     
  12. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    mysql_set_charset
     
  13. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    Вот об этом я и говорил как о наложении разных попаболей. Чем больше у тебя этих "если здесь убрать, а здесь перевернуть", тем меньше ты контролируешь ситуацию. Это снежный ком.

    Сделай тестовую страницу, добейся, чтобы форма воспринималась браузером как utf-8. Никаких соединений с базой, просто header + статичный HTML! Получится?
     
  14. DeadMoroz

    DeadMoroz Новичок

    С нами с:
    27 июн 2013
    Сообщения:
    18
    Симпатии:
    0
  15. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Возможно сам файл у вас не конвертируется при создании в кодировку "UTF-8 (без BOM)".
    Если вы где-то через скрипт создаете файл, видимо там нет конвертации iconv. И конкретной работы с unicode тоже.
    Скачайте Notepad++ у себя на компьютере, в новых версиях поправили конвертирование файлов в "UTF-8 (без BOM)", файл уже создается таким.

    Создайте файл:
    index.html
    Код (PHP):
    1. <!DOCTYPE html>
    2. <html>
    3.    <head>
    4.       <meta charset="utf-8">
    5.       <title>
    6.          Титул страницы
    7.       </title>
    8.    </head>
    9.    <body>
    10.       <div>
    11.          Русский текст!
    12.       </div>
    13.    </body>
    14. </html>
    15.  
    Сохраните и залейте на сервер.
    Будет ли работать?
     
  16. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    да, распознается как utf-8. хотя:

    1. заголовок выглядит так: "Content-Type: text/html" -- без указания charset. видимо это настоящий html-файл без пэхапэшного вызова header(), да?
    2. судя по всему, в этом файле буковки в кодировке 1251.

    когда в header нет указаний на кодировку, браузер полагается на <meta charset>. с этим сейчас порядок.
    возьми редактор, который умеет менять кодировку и пересохрани файл в utf-8. тогда будет ПОЛНЫЙ порядок!

    Добавлено спустя 10 минут 22 секунды:
    многие советуют Notepad+. я для редактирования по-быстрому юзаю встроенный редактор Far Manager 2, он со всеми кириллическими кодировками работает (хотя норовит вставить BOM в UTF-8, но я уже знаю финты как это обойти).
     
  17. DeadMoroz

    DeadMoroz Новичок

    С нами с:
    27 июн 2013
    Сообщения:
    18
    Симпатии:
    0
    2 Your: да, так показывает по-человечески
    2 artoodetoo: да, я тоже использую notepad ++, просто и со вкусом
    ...слушайте, парни, офигеть - усе записалось в базу в лучшем виде
    спасибо вам огромное
    последний вопрос, чтобы разобраться - что не так сделал? неужели кодировка, в которой набирается html, влияет на кодировку пересылаемых им значений?.. или я что-то не так понял?
     
  18. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Выставляйте кодировку правильно и не будет проблем, главное чтобы соответствовала указанным, если "utf-8", значит все должно быть в "unicode" кодировке, если "windows, koir и д. р.", значит должно быть выставлено по ней.
    Чтобы быть уверенным, что работа с данными будет работать с данной кодировкой, потребуется сделать процедуры по:
    - Базе, таблицам, колонкам...
    - Конвертации файлов
    - .htaccess
    - Заголовкам meta, header()
    - Данные с которыми работаем или принимаем

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

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.128
    Симпатии:
    1.248
    Адрес:
    там-сям
    попробую я создать чеклист:

    человек видит не то, что есть на самом деле, а то, к чему он готов.

    иногда "-" накладывается на "-" и получается "+", а иногда "--". не гони, старайся совершать по одной ошибке за раз.

    реальная кодировка текста в файле никак не влияет на автоопределение браузера. для этого есть заголовок http и тег html meta. заголовок "сильнее".

    браузер шлет данные формы в кодировке формы. в какой -- см. выше.

    база данных может иметь любую кодировку, необязательно такую же как у страницы. может быть несколько баз на одном сервере с разными кодировками. в каждой базе могут быть таблицы с разными кодировками и даже поля одной таблицы в разных кодировках. как с этим жить? см. ниже:

    уникод создан с целью объединения всех существующих языков. символы из любой [ 8ми битной ] кодировки могут быть переведены в уникод, а вот наоборот может не получиться. utf-8 это один из способов записи уникода.

    сервер бд умеет пере-кодировать на лету. но если мы ему не сообщим кодировку, то будут использованы настройки сервера по умолчанию (а не кодировка базы!) так давайте ему сообщим нужную кодировку!

    и давайте работать с utf-8! это весело :)
     
  20. DeadMoroz

    DeadMoroz Новичок

    С нами с:
    27 июн 2013
    Сообщения:
    18
    Симпатии:
    0
    мысль понял, большущее спасибо за помощь. Это мои первые шаги в php )
    кстати, насчет - и - = -- тоже верно. Я там косячил еще с iconv(), указывал в первом аргументе исходную кодировку вместо целевой
    просто когда такая вещь как кодировка не получается, начинаешь беситься и гнать волну, меняешь тут и там разные параметры и потом уже теряешь нить происходящего. Буду заваривать чай с ромашкой ) еще раз спасибо