Php 我是否正确消毒/逃生?

Php 我是否正确消毒/逃生?,php,mysql,input,output,mysql-real-escape-string,Php,Mysql,Input,Output,Mysql Real Escape String,我用PHP编写了一个简单的搜索脚本,用于搜索mySQL数据库并输出结果。其工作原理如下: 用户通过搜索表单搜索jack的。 我的PHP脚本获取此搜索,并对其进行清理。 然后脚本使用SELECT和LIKE获得结果。 然后,脚本将结果输出给用户。 最后,脚本告诉用户jack返回了x个结果。在逃跑的帮助下。 我想问的是,我做得对吗 这是我在从数据库中选择之前进行清理的方式: if(isset($_GET['q'])){ if(strlen(trim($_GET['q'])) >= 2){

我用PHP编写了一个简单的搜索脚本,用于搜索mySQL数据库并输出结果。其工作原理如下:

用户通过搜索表单搜索jack的。 我的PHP脚本获取此搜索,并对其进行清理。 然后脚本使用SELECT和LIKE获得结果。 然后,脚本将结果输出给用户。 最后,脚本告诉用户jack返回了x个结果。在逃跑的帮助下。 我想问的是,我做得对吗

这是我在从数据库中选择之前进行清理的方式:

if(isset($_GET['q'])){
  if(strlen(trim($_GET['q'])) >= 2){
    $q = trim(mysql_real_escape_string(addcslashes($_GET['q'], '%_')));
    $sql = "SELECT name, age, address FROM book WHERE name LIKE '%".$q."%'";
  }
}
在输出jack返回的x结果之前,我就是这样逃跑的:

echo htmlspecialchars(stripslashes($q)) . " returned x results.";
这是正确的方法吗

顺便说一句,我知道PDO和mySQLi更受欢迎,因为它们通过使用准备好的语句来净化自己,但我对它们没有任何实际经验。但如果你们能给我链接一些新手教程/解释,我很乐意看一看。
此外,我听说magic_引号和charset可能以某种方式导致注射-这是正确的吗?

出于某种原因,我们也需要注射。 所以,我相信,正确的代码应该是

if(isset($_GET['q'])){
  $_GET['q'] = trim($_GET['q']);
  if(strlen($_GET['q']) >= 2){
    $q = $_GET['q'];
    $q = '%'.addCslashes($q, '\%_').'%';
    // now we have the value ready either for escaping or binding
    $q = mysql_real_escape_string($q);
    $sql = "SELECT name, age, address FROM book WHERE name LIKE '$q'";
    //or 
    $sql = "SELECT name, age, address FROM book WHERE name LIKE ?";
    $stm = $pdo->prepare($sql);
    $stm->execute(array($q));
    $data = $stm->fetchAll();
  }
}
对于输出,使用

echo htmlspecialchars($_GET['q']);
这里不需要斜杠

此外,我听说magic_引号和charset可能以某种方式导致注射-这是正确的吗

如果你不使用魔法引号,它不会损害你的安全。 字符集在某些极为罕见的编码情况下是危险的,但只有在设置不正确的情况下。如果在PDO的情况下使用mysqli_set_charset或DSN,那么您再次安全了


至于PDO,a对于初学者来说应该足够了,我相信您的转义应用的顺序完全错误。也许可以解释一下你认为它是如何工作的。@mario是吗?我不知道哪种顺序更好/更正确。让我解释一下。当脚本获取时,输入将被修剪,并检查输入是否等于或超过2个字符长。之后,它通过首先向%和u添加斜杠来进行清理,以防止通配符搜索,然后通过使用mysql_real_escape_字符串来清理输入,最后,如果输入的开头或结尾有空格,它会进行修剪。现在正在数据库中搜索经过清理的内容。至于逃逸-它是有效的,但我是从一个随机的主题中得到的。嗯,首先修剪,然后是m_r_e_s,然后为类似的glob添加睫毛。好的。但你能像我五岁一样解释一下,不同消毒功能的顺序是如何重要的吗?我是说。。您能否举例说明trim、m_r_e_s、addcslashes与addcslashes、m_r_e_s、trim的工作原理不同/更好?您能否对输出进行评论?我能逃脱吗?我甚至需要htmlspecialchars函数吗?或者可以用更好的东西代替它吗?谢谢你的回答,但是你提供的代码让事情变得更糟。首先,在addCslashes周围使用%是无用的,因为在选择我要做的事情时,可以将它们放在$q周围。最后,输出需要stripslashes,否则它将返回jack返回的x结果,而不是jack返回的x结果。总之,上面的代码与我的代码几乎相同-尽管你的代码添加了斜杠,我将偷它!对不起,你的两个想法都大错特错了。将%s添加到变量后,您可以将其用于转义或绑定。我不会说它更糟。从数据库中读取数据永远不需要条带斜杠。如果您需要它,这意味着您的数据被破坏了,或者是被神奇的引号或者其他错误的代码破坏了。你必须清理它,而不是使用斜杠。我想你误解了这里的一些东西,也许我在我的帖子里没有说清楚。我的输出不是来自您所指出的数据库,而是来自用户输入的内容。是的,我在哪里添加%s很重要,使用stripslashes很重要,因为在输出的情况下我不会从数据库中读取数据。没错。你需要两个变量。我道歉。修正了密码,没问题。顺便说一句,当我在输出上使用htmlspecialchars时,似乎有点像Ömer没有出现,因为ö。这可能是因为一些相互矛盾的字符集设置吗?
if(isset($_GET['q'])){
  $_GET['q'] = trim($_GET['q']);
  if(strlen($_GET['q']) >= 2){
    $q = $_GET['q'];
    $q = '%'.addCslashes($q, '\%_').'%';
    // now we have the value ready either for escaping or binding
    $q = mysql_real_escape_string($q);
    $sql = "SELECT name, age, address FROM book WHERE name LIKE '$q'";
    //or 
    $sql = "SELECT name, age, address FROM book WHERE name LIKE ?";
    $stm = $pdo->prepare($sql);
    $stm->execute(array($q));
    $data = $stm->fetchAll();
  }
}