Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 撇号和反斜杠悖论_Php_Mysql_Sql_Regex - Fatal编程技术网

Php 撇号和反斜杠悖论

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

我对此困惑了一段时间,终于屈服于这里寻求帮助

我有一个用于抓取的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_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元字符。或者可能是参数化查询?