8

我正在将一些数据从表单中插入数据库。我addslashes用来转义文本(也尝试mysql_real_escape_string过相同的结果)。

常规引号会被转义,但其他一些引号不会。例如,字符串:

荷马的血成为萌新啤酒的秘密成分。

转换为:

荷马的血成为萌新啤酒的秘密成分。

我不认为大引号不转义会很重要,但只有这个文本被插入到数据库中:

荷马的血成为萌的秘密成分

所以 PHP 认为花引号很好,但 MySQL 正在丢失字符串。MySQL 没有给出任何错误。

4

2 回答 2

7

我会寻找在您的 Web 界面中使用的字符编码与在数据库级别使用的字符编码之间的不匹配。例如,如果您的 Web 界面使用 UTF-8,并且您的数据库使用默认的 MySQL 编码latin1,那么您需要使用DEFAULT CHARSET=utf8.

顺便说一句,使用mysql_real_escape_string()或mysqli。 不足以防止 SQL 注入addslashes()

于 2009-08-23T16:10:44.370 回答
7

Moe 中的 ' 是示例字符串中唯一无效的字符,如果该字符串是 latin1 编码但您的 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') );

印刷

长度= 5 4D 6F 65 92 73
长度= 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 服务器需要来自客户端 (php) 的 utf8 编码字符。什么是“你的”连接字符集?

然后看看你的参数字符串的实际编码,即如果你有

$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?

于 2009-08-23T16:37:42.740 回答