Страница с кодировкой UTF-8 отправляет данные в MySQL с кодировкой UTF-8, но запись зашифрована

Я понимаю, что есть дюжина подобных вопросов, но ни одно из предложенных там решений не работает в этом случае.

У меня есть переменная PHP на странице, инициализированная как:

$hometeam="Крылья Советов";    //Cyrrilic string

Когда я распечатываю его на странице, он печатает правильно. Таким образом, echo $hometeam отображает строку Крылья Советов, как и должно быть.

Метатег содержимого в заголовке устанавливается следующим образом:

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">

И в самом начале страницы у меня есть следующее (как предложено в одном из решений, найденных в моем поиске):

ini_set('default_charset', 'utf-8');

Так что все должно быть хорошо.

Таблица MySQL, в которую я пытаюсь сохранить это, и рассматриваемый столбец имеют кодировку utf8_bin. Когда я захожу в phpMyAdmin и вручную ввожу Крылья Советов, он правильно сохраняется в поле.

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

mysql_query("insert into tablename (round,hometeam) values ('1','$hometeam') ");

Запись mysql выглядит так:

c390c5a1c391e282acc391e280b9c390c2bbc391c592c391c28f20c390c2a1c390c2bec390c2b2c390c2b5c391e2809ac390c2bec390c2b2

Так что же здесь происходит? Если на странице все в порядке, и с самим MySQL все в порядке, в чем проблема? Есть ли что-то, что я должен добавить к самому запросу, чтобы он сохранял строку в кодировке UTF-8?

Обратите внимание, что я установил mysql_set_charset('utf8'); после подключения к базе данных (вверху страницы).

РЕДАКТИРОВАТЬ: выполнение запроса SHOW VARIABLES LIKE "%character_set%" дает следующее:

Variable_name   Value
character_set_client    utf8
character_set_connection    utf8
character_set_database  latin1
character_set_filesystem    binary
character_set_results   utf8
character_set_server    latin1
character_set_system    utf8
character_sets_dir  /usr/share/mysql/charsets/

Похоже, здесь что-то может быть, так как в этом списке есть 2 латиницы. Что вы думаете?

Кроме того, когда я набираю кириллическую строку непосредственно в phpMyAdmin, сначала она выглядит нормально (она отображается правильно после сохранения). Но перезагружая таблицу, она отображается в HEX, как и вставленные. Прошу прощения за дезинформацию по этому поводу в вопросе. Как оказалось, это должно означать, что проблема связана с phpMyAdmin или самой базой данных.

РЕДАКТИРОВАТЬ № 2: это то, что возвращает show create table tablename:

CREATE TABLE `tablename` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `round` int(11),  `hometeam` varchar(32) COLLATE utf8_bin NOT NULL,  `competition` varchar(32) CHARACTER SET latin1 NOT NULL DEFAULT 'Russia',  PRIMARY KEY (`id`)) ENGINE=MyISAM AUTO_INCREMENT=119 DEFAULT CHARSET=utf8 COLLATE=utf8_bin

person sveti petar    schedule 09.07.2013    source источник
comment
Вы делали запрос типа: SET NAMES 'utf8' раньше? stackoverflow.com/questions/2159434/set-names-utf8 -в-mysql   -  person steven    schedule 09.07.2013
comment
@steven Я этого не делал, нет, но теперь, когда проблема осталась прежней, так что это не помогло.   -  person sveti petar    schedule 09.07.2013
comment
@jovan в какой кодировке находится файл исходного кода? При тестировании в аналогичной настройке с кириллической кодировкой я получаю только пустую строку. С utf8 все идет как надо.   -  person Salem    schedule 09.07.2013
comment
@Salem Кодировка файла тоже UTF-8.   -  person sveti petar    schedule 09.07.2013
comment
@jovan только что подготовил ответ на другой ваш вопрос о командах, жаль, что вы его удалили.   -  person Prix    schedule 10.07.2013
comment
@Prix Извините за это, я обнаружил, что проблема не в запросе - у меня были некоторые ошибочные данные, которые вызывали проблему, поэтому не было смысла беспокоить людей дальше.   -  person sveti petar    schedule 10.07.2013
comment
@jovan хорошо, мой запрос удалил большую часть ваших соединений и упростил большую часть из них, несмотря на то, что вы это поняли.   -  person Prix    schedule 11.07.2013
comment
@Prix Звучит интересно, не могли бы вы поместить это для меня в pastebin (если он у вас еще есть)?   -  person sveti petar    schedule 11.07.2013
comment
строка базы данных это varchar или char?   -  person jycr753    schedule 14.07.2013
comment
Кроме того, если вы print_r $_POST у вас есть правильные значения там?   -  person jycr753    schedule 14.07.2013
comment
@jycr753 jycr753 Это варчар. POST-а нет, это не форма - чищу строки с интернет-ресурса. Но если я наберу строку самостоятельно, а не соскребаю ее, проблема останется той же, поэтому источник строк не имеет значения.   -  person sveti petar    schedule 14.07.2013
comment
Какая версия PHP? Когда вы говорите, что запись mysql выглядит как ... c390c5a1..., где вы это видите? Это то, что вы получите, если SELECT HEX(hometeam) FROM tablename WHERE round = '1' (а если нет, что делаете вы получите в ответ на этот запрос)?   -  person eggyal    schedule 15.07.2013


Ответы (4)


Кроме того, когда я набираю кириллическую строку непосредственно в phpMyAdmin, сначала она выглядит нормально (она отображается правильно после сохранения). Но перезагружая таблицу, она отображается в HEX, как и вставленные.

Это почти наверняка похоже на проблему в вашей таблице! Выполнить show create table tablename. Бьюсь об заклад, что вместо utf8 есть latin1, потому что он установлен по умолчанию в переменной character_set_database.

Чтобы изменить это, выполните следующую команду:

ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;

Это преобразует все ваши varchar поля в utf8. Но будьте осторожны с записями, которые у вас уже есть в таблице, так как они уже искажены, если вы преобразовали их в UTF8, они останутся искаженными. Возможно, лучше всего снова создать базу данных, просто добавив следующие команды в конце определения таблицы:

CREATE TABLE `tablename` (
    ....
) ENGINE=<whatever you use> DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci
person Tomas    schedule 17.07.2013
comment
@jovan, тогда попробуй изменить utf8_bin на utf8_general_ci. И помните, что ваш столбец competition по-прежнему латинский1. - person Tomas; 17.07.2013
comment
Да не то чтобы я менял сортировку и таблицы и столбца на utf8_general_ci, работает. Спасибо! - person sveti petar; 17.07.2013

Вы получаете эту шестнадцатеричную строку в phpMyAdmin? Я полагаю, когда вы SELECT вставляете значение, например. PHP или консольный клиент MySQL вам будет предоставлена ​​ожидаемая кириллическая строка UTF8.

Если это так, это проблема конфигурации с phpMyAdmin, см., например. здесь: http://theyuri.blogspot.ch/2010/12/phpmyadmin-collated-db-in-utf8bin-shows.html

Сопоставленная база данных phpMyAdmin в utf8_bin показывает шестнадцатеричные данные вместо текста UTF8

$cfg['DisplayBinaryAsHex'] = ложь;

Кроме того, пожалуйста, не используйте mysql_query таким образом, поскольку вы полностью открыты для SQL-инъекций. Я также не уверен, действительно ли вы хотите использовать utf8_bin, см., например. это обсуждение: utf8_bin vs. utf_unicode_ci или это: UTF-8: общий? Бин? Юникод?

EDIT Происходит что-то странное. Если вы переведете данную шестнадцатеричную строку в символы UTF8, вы получите следующее: -decoder/utf8-decoder" rel="nofollow noreferrer">http://software.hixie.ch/utilities/cgi/unicode-decoder/utf8-decoder). Если вы utf8_decode это, вы получите желаемые Крылья Советов. Итак, кажется, что он как минимум дважды закодирован в utf8 (помимо проблемы, что он где-то отображается как шестнадцатеричные символы).

Не могли бы вы предоставить полный сценарий? Вы где-нибудь utf8_encode свою строку? Если ваш скрипт это и только это (кроме действительного открытого соединения MySQL):

<?php
$hometeam="Крылья Советов";    //Cyrrilic string
// open mysql connection here
mysql_set_charset('utf8');
mysql_query("INSERT INTO tablename (round, hometeam) VALUES ('1', '$hometeam')");
$result = mysql_query("SELECT * FROM tablename WHERE round = '1'");
$row = mysql_fetch_assoc($result);
echo $row['hometeam'];
?>

А вы вызываете страницу, что в результате (в исходнике страницы браузера, а не в том, что отображается в браузере)?

Кроме того, проверьте, что произойдет, если вы измените параметры сортировки на utf8_unicode_ci, как это предлагается в другом ответе здесь. Это, по крайней мере, охватывает проблемы phpMyAdmin при отображении двоичных данных и, возможно, в любом случае то, что вам нужно (поскольку вы, вероятно, хотите, чтобы предложения ORDER BY работали должным образом, см. обсуждения в вопросах SO, которые я связал выше).

EDIT2 Возможно, вы также могли бы предоставить некоторые фрагменты, такие как SHOW CREATE TABLE tablename или SHOW VARIABLES LIKE "%character_set%". Может помочь.

person stef77    schedule 14.07.2013
comment
Когда я распечатываю значения из базы данных (я пробовал это с utf_encode и без него), я не получаю правильный кириллический текст. Что касается SQL-инъекций, я знаю об этом, спасибо. Это только пример. Это на общем хостинге, поэтому я не думаю, что смогу настроить phpMyAdmin таким образом. - person sveti petar; 15.07.2013
comment
Чтобы уточнить: когда вы ВЫБИРАЕТЕ значение, вы получаете шестнадцатеричную строку, которую вы упомянули? Где и как вы распечатываете значения из базы данных? - person stef77; 17.07.2013
comment
Пожалуйста, взгляните на мой отредактированный ответ, возможно, мы сможем узнать больше, когда вы предоставите дополнительную информацию. - person stef77; 17.07.2013
comment
Извините за задержку, я сейчас разговариваю по телефону и утром сделаю то, что вы предложили. - person sveti petar; 17.07.2013
comment
Я не использую utf_encode в коде PHP. Если я использую фрагмент кода, который вы предложили на странице, правильная кириллическая строка появляется как на странице, так и в исходном коде страницы. Полный исходный код страницы находится здесь: pastebin.com/1RtAJ0RQ. кто-то может попробовать на своем сервере. Вы правы, что защиты от инъекций нет, я снял ее во время тестирования, чтобы посмотреть, не связано ли это с этим. Сейчас работаю над другими вашими предложениями. - person sveti petar; 17.07.2013

1) Попробуйте сохранить запись в базу с помощью PhpMyAdmin, а затем также посмотрите результат в PhpMyAdmin. Выглядит нормально? Если да, база данных создана и настроена правильно.

2) Попробуйте вместо этого использовать utf8_general_ci. Это не должно иметь значения, но попробуйте.

3) Настройте все необходимые параметры на стороне PHP — следуйте этому сообщению: http://blog.loftdigital.com/blog/php-utf-8-cheatsheet . Особенно попробуйте этот трюк:

echo htmlentities($hometeam, ENT_QUOTES, 'UTF-8')
person Tomas    schedule 16.07.2013
comment
Я думаю, что проблема почти наверняка связана с базой данных - пожалуйста, проверьте мое редактирование вопроса. - person sveti petar; 17.07.2013
comment
@jovan Я прочитал ваше обновление - значит, проблема точно в вашей таблице! Пожалуйста, сообщите о полном выводе show create table tablename! - person Tomas; 17.07.2013
comment
Я добавил вывод в вопрос. Мне кажется, все в порядке - может быть, проблема в общей конфигурации MySQL? Поскольку это виртуальный хостинг, возможно, я мог бы попросить ребят из службы поддержки хостинга помочь мне? Кстати пробовал переходить на utf8_general_ci, ничего не изменилось. - person sveti petar; 17.07.2013
comment
Не обращайте внимания на приведенный выше комментарий - когда я изменил параметры сортировки как таблицы, так и столбца, все заработало нормально. Кстати, есть идеи, почему это произошло? Разве utf_bin не должен работать для всего? - person sveti petar; 17.07.2013
comment
@jovan (вы, вероятно, также ссылаетесь на мой другой ответ) - это не очень ясно, однако я думаю, что utf8_general_ci должен работать для всего. - person Tomas; 17.07.2013

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

Я предполагаю, что у вас неправильная конфигурация кодировки, потому что я видел это в официальной документации Документация по MySQL

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

Тот, который я пробовал в другом проекте, состоит в преобразовании строки с использованием url_encode($string) и url_decode($string).

person David Level    schedule 17.07.2013