Я вставляю некоторые данные в базу данных из формы. Я использую addslashes
чтобы избежать текста (также попробовал mysql_real_escape_string
с тем же результатом).
Регулярные кавычки экранируются, но некоторые другие цитаты отсутствуют. Например, строка:
Кровь Гомера становится секретным ингредиентом нового пива Мо.
преобразуется в:
Гомерская кровь становится секретным ингредиентом нового пива Мо.
Я не думал, что курчавая цитата будет иметь значение без привязки, но только этот текст вставляется в базу данных:
Гомерская кровь становится секретным ингредиентом в Мое
Поэтому PHP считает, что курчавая цитата прекрасна, но MySQL теряет строку. Однако MySQL не дает никаких ошибок.
Я искал бы несоответствие между кодировкой символов, используемой в вашем веб-интерфейсе, и используемой на уровне базы данных. Например, если ваш веб-интерфейс использует UTF-8, и ваша база данных использует кодировку MySQL по умолчанию для latin1
, вам необходимо настроить свои таблицы с помощью DEFAULT CHARSET=utf8
.
mysql_real_escape_string()
используйте mysql_real_escape_string()
или mysqli. addslashes()
является адекватной защитой от SQL-инъекции.
«В Moe's – единственный символ в вашей строке примера, который недействителен, если эта строка кодируется латином1, но ваш сервер mysql ожидает utf8.
Простая демонстрация:
<?php function foo($s) { echo 'len=', strlen($s), ' '; for($i=0; $i<strlen($s); $i++) { printf('%02X ', ord($s[$i])); } echo "\n"; } // my file is latin1 encoded and so is the string literal foo('Moe's'); // now try it with an utf8 encoded string foo( utf8_encode('Moe's') );
печать
len = 5 4D 6F 65 92 73
len = 6 4D 6F 65 C2 92 73
Поэтому возникает вопрос: кормите сервер mysql чем-то «неправильным» кодированием?
Каждое соединение имеет кодировку соединений, а сервер mysql ожидает, что ваш клиент (php-скрипт) отправит данные, закодированные в этом наборе символов. Вы можете узнать, с чем связана цепочка соединений.
SHOW VARIABLES LIKE '%character%'
как в
$mysql = mysql_connect('..', '..', '..') or die(mysql_error()); mysql_select_db('..', $mysql) or die(mysql_error()); $query = "SHOW VARIABLES like '%character%'"; $result = mysql_query($query, $mysql) or die(__LINE__.mysql_error()); while( false!==($row=mysql_fetch_array($result, MYSQL_ASSOC)) ) { echo join(', ', $row), "\n"; }
Это должно печатать что-то вроде
character_set_client, utf8 character_set_connection, utf8 character_set_database, latin1 character_set_filesystem, binary character_set_results, utf8 character_set_server, utf8 character_set_system, utf8
и character_set_connection, utf8
указывает, что «мой» набор символов подключения – utf8, то есть сервер mysql ожидает кодировку utf8 из клиента (php). Что такое «ваша» цепочка соединений?
Затем взгляните на фактическую кодировку вашей строки параметров, то есть, если у вас есть
$foo = mysql_real_escape_string($_POST['foo'], $mysql);
замените это на
echo '<div>Debug hex($_POST[foo])='; for($i=0; $i<strlen($s); $i++) { printf('%02X ', ord($_POST['foo'][$i])); } echo "</div>\n"; $foo = mysql_real_escape_string($_POST['foo'], $mysql);
и проверьте, какова фактическая кодировка вашей входной строки. Печатает ли он 92 или C2 92?