Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 1 из 4 1 2 3 ... ПоследняяПоследняя
Показано с 1 по 10 из 39
  1. #1
    Аватар для $continue$
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.08.2014
    Адрес
    г. Киров (aka Вятка)
    Сообщений
    1,487
    Репутация:
    276 ±

    Решение проблемы с кодировкой в MySQL | R33+

    Цитата Сообщение от DeimoS Посмотреть сообщение
     Немного логических рассуждений и теории
    Меня уже долгое время смущал вариант "настройки" кодировки от $continue$, ибо хоть я особо и не интересовался никогда ковырянием кодировки в MySQL (просто нужды не было), но знал, что вот этот запрос:
    1. SET CHARACTER SET 'utf8'

    является групповым. То бишь, отправляя этот единственный запрос, Вы, сразу настраиваете три параметра (*документация*) и он равносилен таким трём запросам:
    1. SET character_set_client = utf8;
    2. SET character_set_results = utf8;
    3. SET collation_connection = @@collation_database;

    И если взглянуть на запросы, которые $continue$ предлагает отправлять, можно заметить там идентичные запросы.

    Но если про "SET CHARACTER SET" я узнал совершенно "случайно", то с запросом "SET NAMES" мне так не повезло и до текущего момента я не знал какие запросы он в себе скрывает. В итоге, документация говорит про три таких запроса:
    1. SET character_set_client = utf8;
    2. SET character_set_connection = utf8;
    3. SET character_set_results = utf8;

    И вновь мы видим запросы на изменение тех же опций, которые мало того, что содержатся в "SET CHARACTER SET", так ещё и впоследствии изменяются отдельными запросами с "utf8" на "cp1251".

    Иными словами, таким вот "решением проблемы с кодировкой", которое дано в теме, Вы каждый раз будете "дёргать" одни и те же опции, изменяя их значение с одного на другое.




    На этой ноте можно было бы закончить, но мне стало интересно окончательно закрыть тему кодировки для SA-MP. И я был бы не я, если бы не поделился найденной информацией с Вами :) Заодно, если я вдруг ошибусь, кто-то сможет меня поправить.

    Маленькая оговорка касаемо определений:
    Сервер - это наш сервер MySQL с базами дарных, блекджеком и всем остальным.
    Клиент - это, в нашем случае, сервер SA-MP
    Так же стоит понимать, что все опции настраивают именно сервер MySQL. Даже опция, связанная с кодировкой запросов от клиента, влияет именно на сервер, так как именно он будет заниматься конвертированием данных. То бишь, уяснили: все операции с данными происходят не на стороне сервера SA-MP или плагина, а именно на стороне сервера MySQL. И всеми опциями мы лишь сообщаем серверу MySQL нужную информацию для того, чтоб он совершил конвертирование.



    Давайте разберёмся с основными опциями, которые нам могут пригодится. В случае с SA-MP нам потребуется всего несколько, так как остальные MySQL либо самостоятельно подстроит под эти запросы, либо они уже настроены как надо по умолчанию.

    • character_set_client - В этой опции указaывается кодировка, в которой будут поступать данные от клиента к серверу.
    • character_set_results - В этой опции указывается кодировка, в которую сервер конвертирует данные перед отправкой их клиенту.
    • character_set_connection - В этой опции указывается кодировка, в которую сервер перекодирует данные, полученные от клиента, перед тем, как начнёт выполнять запрос (клиент->character_set_connection->сервер)


    Собственно, всё. Опция collation_connection, которую предлагает настроить $continue$, для каждой кодировки имеет установку по умолчанию, которая, в случае с utf8, будет равна как раз "utf8_general_ci", поэтому определять её самостоятельно нет смысла.
      Открыть/закрыть
    Если кому интересно, посмотреть "настройки по умолчанию" для той или иной кодировки можно при помощи запроса
    PHP код:
    SHOW COLLATION WHERE charset 'имя_кодировки'
    Результатом запроса будет список всех доступных вариантов представления для указанной кодировке и напротив того представления, которая является представлением по умолчанию, в столбце "Default" будет стоять "Yes".

    Вот пример результата для utf8
    PHP код:
    SHOW COLLATION WHERE charset 'utf8' 






    Теперь осталось действительно решить все проблемы с кодировкой, дабы всё работало как надо.
    В чём заключается проблема? В том, что сервер не знает в какой кодировке работает клиент, из-за чего не может правильно конвертировать данные, пришедшие от клиента и подготовить данные к отправке для клиента. И если Вы взгляните на те 3 опции, что я перечислил выше, то найдёте решение всем проблемам.
    Я не зря расписал то, в чём заключается проблема, ибо если Вы сейчас перечитаете составленное мной определение, то увидите, что в обоих случаях фигурирует именно клиент. А с какой кодировкой работает наш клиент? Правильно, cp1251. Поэтому все те свистопляски с 'utf8', которые устроил $continue$ в своём варианте, бессмысленны (можно разве что в character_set_server передавать "utf8", если Вы не уверены в том, что сервер MySQL изначально настроен под эту кодировку).


    Этих двух запросов должно целиком и полностью хватить для хранения русского текста в базе (с учётом того, что Вы никак не правили остальные настройки кодировки и они выставлены по умолчанию или же настроены правильно):
    1. mysql_query(var_connection, "SET character_set_client = 'cp1251'", false);// Определяем кодировку для запросов от сервера SA-MP к базе
    2. mysql_query(var_connection, "SET character_set_results = 'cp1251'", false);// Определяем кодировку от базы данных к нашему серверу SA-MP

    Как минимум, вся та каша из запросов, что даёт $continue$, точно не нужна.

     Опциональные запросы:
    1. mysql_query(var_connection, "SET SESSION character_set_server='utf8'", false);// Устанавливаем кодировку, в которой данные будут хранится на сервере MySQL (кодировка самого сервера, иными словами)


    P.S. Всё это подкреплено лишь моим маленьким "расследованием" (копанием документации) и простыми тестами на локальном сервере с дефолтными настройками MySQL, так что было бы неплохо проверить все мои доводы в более разных условиях, дабы уже окончательно отшлифовать код, если вдруг я чего-то не учёл.
    Засим я откланиваюсь Надеюсь, что у меня получилось понятно объяснить Вам назначение перечисленных опций. Спасибо за внимание


     Изначальный текст темы
    Доброго времени суток! В интернете есть много решение данной проблемы (на форумах по Pawn), но они то не работают, то выбивают ошибку в лог. Пример кода при котором в лог идет ошибка:
    PHP код:
    mysql_set_charset(!"utf8_bin");
    mysql_function_query(MYSQL_ARG, !"SET NAMES 'utf8'"false"""");
    mysql_function_query(MYSQL_ARG, !"SET CHARACTER SET 'cp1251'"false""""); 
    Ошибка в логах:
      Открыть/закрыть



    Решение данной проблемы я все таки добился. И хочу поделиться с Вами: (до версии R40)
    PHP код:
    SetMySQLEncoding(var_connection)
    {
        
    mysql_function_query(var_connection, !"SET CHARACTER SET 'utf8'"false"""");
        
    mysql_function_query(var_connection, !"SET NAMES 'utf8'"false"""");
        
    mysql_function_query(var_connection, !"SET character_set_client = 'cp1251'"false"""");
        
    mysql_function_query(var_connection, !"SET character_set_connection = 'cp1251'"false"""");
        
    mysql_function_query(var_connection, !"SET character_set_results = 'cp1251'"false"""");
        
    mysql_function_query(var_connection, !"SET SESSION collation_connection = 'utf8_general_ci'"false"""");

    После версии R40:
    PHP код:
    SetMySQLEncoding(MySQL:var_connection)
    {
        
    mysql_tquery(var_connection, !"SET CHARACTER SET 'utf8'""""");
        
    mysql_tquery(var_connection, !"SET NAMES 'utf8'""""");
        
    mysql_tquery(var_connection, !"SET character_set_client = 'cp1251'""""");
        
    mysql_tquery(var_connection, !"SET character_set_connection = 'cp1251'""""");
        
    mysql_tquery(var_connection, !"SET character_set_results = 'cp1251'""""");
        
    mysql_tquery(var_connection, !"SET SESSION collation_connection = 'utf8_general_ci'""""");

    Пример использование (сразу после mysql_connect):
    PHP код:
    SetMySQLEncoding(mysql_connect_ID); // Где mysql_connect_ID - Подключение к базе данных 
    Почитать о character_set.
    Возможно у Вас есть более простое решение данной проблемы. Я буду рад если Вы поделитесь решением.
    Последний раз редактировалось DeimoS; 21.06.2020 в 12:59.
    Value your freedom or you will lose it, teaches history. "Don't bother us with politics," respond those who don't want to learn. (c) Richard Stallman

  2. 3 пользователя(ей) сказали cпасибо:
    #Vito (17.06.2016) JohnConor (01.07.2017) Sp1ke (23.04.2016)
  3. #2
    Аватар для DmX
    Пользователь

    Статус
    Оффлайн
    Регистрация
    22.04.2013
    Адрес
    Краснодар
    Сообщений
    292
    Репутация:
    23 ±
    Очень полезный урок, Данил очень помог мне :)

  4. #3
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    PHP код:
    SetEncodingMySQL(var_connection

        
    mysql_function_query(var_connection, !"SET CHARACTER SET 'utf8'"false""""); 
        
    mysql_function_query(var_connection, !"SET NAMES 'utf8'"false""""
        
    mysql_function_query(var_connection, !"SET character_set_client = 'cp1251'"false""""); 
        
    mysql_function_query(var_connection, !"SET character_set_connection = 'cp1251'"false""""); 
        
    mysql_function_query(var_connection, !"SET character_set_results = 'cp1251'"false""""); 
        
    mysql_function_query(var_connection, !"SET SESSION collation_connection = 'utf8_general_ci'"false""""); 

    Точки с запятой нет в конце :)
    PHP код:
    mysql_function_query(var_connection, !"SET NAMES 'utf8'"false""""
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  5. Пользователь сказал cпасибо:
    $continue$ (19.03.2016)
  6. #4
    Аватар для $continue$
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.08.2014
    Адрес
    г. Киров (aka Вятка)
    Сообщений
    1,487
    Репутация:
    276 ±
    Thank, DeimoS. Fix, update.
    Value your freedom or you will lose it, teaches history. "Don't bother us with politics," respond those who don't want to learn. (c) Richard Stallman

  7. #5
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от $continue$ Посмотреть сообщение
    Thank, DeimoS. Fix, update.
    "Благодарить, DeimoS. Исправлять, обновлять."
    Lol'd.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  8. 2 пользователя(ей) сказали cпасибо:
    Desulaid (23.03.2016) Mexanizm (17.05.2018)
  9. #6
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    "Благодарить, DeimoS. Исправлять, обновлять."
    Lol'd.
      Открыть/закрыть
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  10. #7
    Аватар для $continue$
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.08.2014
    Адрес
    г. Киров (aka Вятка)
    Сообщений
    1,487
    Репутация:
    276 ±
    Да, да ты опять поймал меня с плохим знанием English/Russian Language :(
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    "Благодарить, DeimoS. Исправлять, обновлять."
    Lol'd.
    Value your freedom or you will lose it, teaches history. "Don't bother us with politics," respond those who don't want to learn. (c) Richard Stallman

  11. #8
    Аватар для seriu
    Пользователь

    Статус
    Оффлайн
    Регистрация
    29.11.2013
    Сообщений
    69
    Репутация:
    6 ±
    Уже давно как-то сделал только это:
    PHP код:
    mysql_function_query(base, !"SET NAMES cp1251"false"""" ); 
    И никаких "???????" нету.

  12. #9
    Аватар для $continue$
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.08.2014
    Адрес
    г. Киров (aka Вятка)
    Сообщений
    1,487
    Репутация:
    276 ±
    Включи полное логирование (HTML формат) и скинь логи. Вот только сервер под управлением Linux
    Цитата Сообщение от seriu Посмотреть сообщение
    Уже давно как-то сделал только это:
    PHP код:
    mysql_function_query(base, !"SET NAMES cp1251"false"""" ); 
    И никаких "???????" нету.
    Последний раз редактировалось $continue$; 03.06.2016 в 21:54.
    Value your freedom or you will lose it, teaches history. "Don't bother us with politics," respond those who don't want to learn. (c) Richard Stallman

  13. #10
    Аватар для seriu
    Пользователь

    Статус
    Оффлайн
    Регистрация
    29.11.2013
    Сообщений
    69
    Репутация:
    6 ±
    Цитата Сообщение от $continue$ Посмотреть сообщение
    Включи полное логирование (HTML формат) и скинь логи. Вот только сервер под управлением Linux
    http://i.imgur.com/MofrHLe.png
    https://yadi.sk/d/r2ZnXERmsF9rW
    хостинг: myarena ( linux )
    п.с я сделал отдельную таблицу для команды "/su" т.е записывается в бд "wanted" причину
    "11:41:05 CMySQLResult::GetRowDataByName OK row: '0', field: "Reason0", data: "ÒÅÑÒ ïàì ïàì "
    Но, на сервере все отображается как нужно.
    Последний раз редактировалось seriu; 04.06.2016 в 11:52.

 

 
Страница 1 из 4 1 2 3 ... ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •