PDO UPDATE似乎没有存储报价?

时间:2013-09-14 19:38:34

标签: php mysql sql pdo sql-update

我刚刚开始使用PDO方法,现在我遇到了一个小问题。如果我创建一个表单以将名字和姓氏插入数据库,我可以使用以下代码插入所有类型的特殊字符:

try {
    $db = new PDO('mysql:dbhost=' . $dbhost . ';dbname=' . $dbname, $dbuser, $dbpass);
    $db -> exec("SET CHARACTER SET utf8");
} catch(PDOException $e) {
    echo $e->getMessage();
}
$query = $db->prepare("INSERT INTO users(fname, lname) VALUES(:fname, :lname)");
$insert_array = array(
    ":fname" => $fname,
    ":lname" => $lname
);
$query->execute($insert_array);
$db = NULL;

我可以毫无问题地插入":;,-!"#¤%&&(%)?{][]}£$€{{{$@@_--",甚至可以插入SQL注入。但是当我尝试使用类似的代码更新数据库时,它会接受除引号之外的所有类型的特殊字符。这是为什么?我用来更新的代码是:

try {
    $db = new PDO('mysql:dbhost=' . $dbhost . ';dbname=' . $dbname, $dbuser, $dbpass);
    $db -> exec("SET CHARACTER SET utf8");
} catch(PDOException $e) {
    echo $e->getMessage();
}
$query = $db->prepare("UPDATE users SET fname=:fname, lname=:lname WHERE userid=:userid");
$update_array = array(
    ":fname" => $fname,
    ":lname" => $lname,
    ":userid" => $_GET['userid']
);
$query->execute($update_array);
$db = NULL;

我很感激能得到的所有帮助。

- =液= -

我不得不使用htmlspecialchars()来“解码”字符串。像这样:

<form action="" method="post">
    First name<br><input type="text" name="fname" value="'.htmlspecialchars($user['fname']).'">
    Last name: <br><input type="text" name="lname" value="'.htmlspecialchars($user['lname']).'">
    <input type="submit">
</form>

现在各种特殊字符都很完美。 感谢所有人的帮助,真的很感激! :d

1 个答案:

答案 0 :(得分:1)

我相信,Waleed Khan是正确的。在这种情况下,不一定要自己解决(虽然这是你在这里显示的一个明显的漏洞,并为这些攻击敞开大门),而是只是打破你的html到目前为止。

通过回显原始的$user['fname']$user['lname']值 - 包含上一次提交的双引号 - 您无意中允许在绘制时过早关闭html元素属性值,从而破坏您的HTML表单。令人惊讶的是它仍然提交。在你的浏览器中,查看Firebug之类的内容并检查表单 - 你应该看到输入结构奇怪,可能会在它之后绘制一些额外的字符。

在PHP值中直接回显它们之前,始终对PHP值使用htmlentities()或其他类似的转义助手函数。总是

示例:

<form action="" method="post">
    First name<br><input type="text" name="fname" value="<?php echo htmlentities( $user['fname'], ENT_COMPAT, 'UTF-8' ); ?>">
    Last name: <br><input type="text" name="lname" value="<?php echo htmlentities( $user['lname'], ENT_COMPAT ); ?>">
    <input type="submit">
</form>

编辑:关于你声称“如果我删除表单值中的引号,它正在使用引号进行更新”,我认为这意味着您使用单引号而不是双引号来设置HTML元素属性值引用,它根本不起作用。

如果用户提交了带单引号的值,则同样会破坏您的固定示例,因为值中的单引号会过早地关闭HTML元素属性值声明。使用双引号来声明HTML元素属性值是最好的,但如果在构建HTML元素时选择使用单引号,则在PHP中使用htmlentities($string, ENT_QUOTES)

请研究htmlentities手册页以确保您正确使用它。