Php 撇号和反斜杠悖论
我对此困惑了一段时间,终于屈服于这里寻求帮助 我有一个用于抓取的preg_match脚本,它匹配循环中的不同变量,并将它们存储在数组中,最后发布到SQL表中。每当变量包含撇号时,就会出现此问题 下面是我如何获取和组织数据的Php 撇号和反斜杠悖论,php,mysql,sql,regex,Php,Mysql,Sql,Regex,我对此困惑了一段时间,终于屈服于这里寻求帮助 我有一个用于抓取的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
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_query("INSERT INTO table (name) VALUES ('".$laeger[$i]['navn']."'")"); or die(mysql_error());
如果我想将其回送到页面,我可以成功地正确回送D'angelo
(带撇号)
请告诉我迈克尔·德安吉洛的名字
但当涉及到将其存储在数据库中时,我遇到了一个悖论;我可以选择将其存储为Michael D'Angelo
或存储数据,并接收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...............)
下面是我存储数据的方式
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_query("INSERT INTO table (name) VALUES ('".$laeger[$i]['navn']."'")"); or die(mysql_error());
取决于我是否使用斜杠,我会搞乱查询或搞乱结果(用闪光灯)。FML.没有悖论。你只是不明白逃跑是怎么回事 如果您有:
INSERT INTO sometable (fieldname) VALUES ('Michael D\'Angelo')
该反斜杠不会被输入数据库的磁盘存储中。它由数据库的SQL解析器剥离出来。类似地,当您从表中检索名称时,它也不会被转义。您将得到Michael D'Angelo
返回给您的客户
您存在一个SQL注入攻击漏洞—允许包含SQL元字符的原始用户提供的数据出现在SQL上下文中,而不考虑这些元字符
这就是为什么(对于旧式代码)会出现类似于
mysql\u real\u escape\u string()
的东西,它会转义所提供字符串中的所有SQL元字符,因此它们会变成纯文本,不再是“元”字符。正如您在评论中所指出的,接受的答案对您没有任何帮助。只有当您事先知道要刮取哪些数据,以便将反斜杠放在正确的位置时,它才会起作用,但当然,您事先不知道,因此需要一个在运行时起作用的解决方案。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”的“helper函数”,它将撇号环绕在escape函数周围,使所有内容更加紧凑、可读性更强、可在数据库之间传输,并且能够抵御SQL注入攻击。
stripslashes
撤销了mysql\u real\u escape\u string所做的事情。这就是为什么输出是不可替换的,并且不适合以后的SQL字符串上下文。我认为您不理解什么是悖论。所以最合理的解决方案是什么?我有点搞不懂逃跑怎么会变成回声。把逃跑当作包装礼物一样对待。包装可以防止礼物在到达收件人之前被“看见”。一旦它这样做了,它就被拆开并使用。包装被用户丢弃。因此,Michael D'Angelo
被“包装”为数据库。它在实际数据文件中展开并存储Michael D'Angelo
。一旦“
实际存储在数据库中,它就不能再“中断”查询语句,因为数据库知道它是字符串的一部分,而不是sql元字符。或者可能是参数化查询?