我一直在困惑这一段时间,并且终于屈服于在这里寻求帮助。
我有一个用于抓取的preg_match脚本,它匹配循环中的不同变量并将它们存储在一个数组中,最后发布到SQL表中。只要变量包含撇号,就会出现问题。
以下是我抓取和整理数据的方法
for($i = 0; $i < count($bokse[0]); $i++){
preg_match_all("/title=\"Mere information om (.+?)\"/sim", $bokse[0][$i], $name, PREG_SET_ORDER);
$laeger[$i]['navn'] = stripslashes(mysql_real_escape_string($name[0][1]));
}
现在,我抓住的东西,mysql_escaped和剥离的值可以是:
**Michael D'Angelo** [NOTICE THE APOSTROPHE]
如果我想将此回显到页面,我可以成功地正确回显D'angelo
(使用撇号)
echo $laeger[$i]['navn'];
会给我Michael D'Angelo
。
但是当把它存储在数据库中时,我遇到了一个悖论;我可以选择将其存储为Michael D\'Angelo
或者存储D,并收到SQL错误。
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'angelo'
(..........blablabv...............)
以下是我存储数据的方式
mysql_query("INSERT INTO table (name) VALUES ('".$laeger[$i]['navn']."'")"); or die(mysql_error());
根据我是否使用striplashes,我要么搞乱查询,要么弄乱结果(使用bachflash)。 FML。
答案 0 :(得分:5)
没有悖论。你只是不明白逃脱是如何运作的。
如果你有:
INSERT INTO sometable (fieldname) VALUES ('Michael D\'Angelo')
反斜杠将 NOT 输入数据库的磁盘存储。它被数据库的SQL解析器剥离了。同样,当您从表中检索名称时,它不会被转义。您将Michael D'Angelo
返回给您的客户。
您所拥有的是SQL注入攻击漏洞 - 允许包含SQL元字符的原始用户提供的数据出现在SQL上下文中,而不考虑这些元字符。
这就是为什么(对于老派代码)像mysql_real_escape_string()
这样的东西会逃避提供的字符串中的所有SQL元字符,因此它们变成纯文本而不再是“元”。
答案 1 :(得分:1)
正如您在评论中指出的那样,接受的答案对您没有任何帮助。它只会提前知道你要抓取哪些数据才能正常工作,这样你就可以将反斜杠放在正确的位置,但当然你事先并不知道所以你需要一个能在运行时运行的解决方案。 MySQL为您提供了这样的解决方案。
解决问题的答案是将插入更改为:
mysql_query("INSERT INTO table (name) VALUES ('".mysql_real_escape_string($laeger[$i]['navn'])."'")");
或者我喜欢这样做,即使它是非标准的:
mysql_query("INSERT INTO table set name='".mysql_real_escape_string($laeger[$i]['navn'])."'");
我认为编码更容易,阅读也更容易。
对于我自己的工作,我创建了一个名为“dbstring”的“辅助函数”,它包含了转义函数周围的撇号,这使得所有内容都更紧凑,更易读,可在数据库之间传输,并且可以防止SQL注入攻击。