【问题标题】:mysql_real_escape_string and single quotemysql_real_escape_string 和单引号
【发布时间】:2009-07-29 15:08:03
【问题描述】:

我很沮丧。我希望能够在我的数据库名称中插入单引号 - 例如,O'Connor。

所以,当插入数据库时​​,我会这样做:

 $lname = mysql_real_escape_string($_POST['lname']);

然后我将 $lname 插入数据库。

当它在数据库中时,它显示为 O\'Connor。

所以,如果我要在我的网络应用程序中回忆那个姓氏,我将不得不使用:

 $lname = stripslashes($r["lname"]);

这一切似乎都很好。但是,我有一个搜索功能,可以搜索姓氏并显示结果。当我搜索时,我必须搜索 O\'Connor 才能得到任何结果。

你看,在我搜索之后,文本框会自动存储刚刚搜索的值(使用会话)。所以我的代码是这样的:

 $search = mysql_real_escape_string($_GET['search']);
 $_SESSION['search'] = $search;

就像我之前说的,当我搜索时,我必须使用“O\'Connor”,然后我搜索后,文本框中的值变成了“O\\\\'Connor”

试图弄清楚这一点令人沮丧。有谁知道我做错了什么?谢谢!

编辑:

这是我的 php5.ini 文件,关于魔术引号:

 ; Magic quotes
 ;

 ; Magic quotes for incoming GET/POST/Cookie data.
 magic_quotes_gpc = On

 ; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc.
 magic_quotes_runtime = Off

 ; Use Sybase-style magic quotes (escape ' with '' instead of \').
 magic_quotes_sybase = Off

但是,我的网站托管在 GoDaddy 上,我没有编辑文件的权限:(

【问题讨论】:

    标签: php mysql escaping mysql-real-escape-string


    【解决方案1】:

    听起来Magic Quotes 在您的 PHP 配置中已启用。

    检查它是否实际启用:

    echo get_magic_quotes_gpc();
    

    To disable,编辑你的 php.ini 文件:

    ; Magic quotes
    ;
    
    ; Magic quotes for incoming GET/POST/Cookie data.
    magic_quotes_gpc = Off
    
    ; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc.
    magic_quotes_runtime = Off
    
    ; Use Sybase-style magic quotes (escape ' with '' instead of \').
    magic_quotes_sybase = Off
    

    或者将此行添加到您的 .htaccess 中:

    php_flag magic_quotes_gpc Off
    

    【讨论】:

    • 他没有魔术引号,他只是在转义一个转义值。
    • 我没看到他两次逃到哪里。对我来说,似乎 $_POST['lname'] 已经被转义了,所以在调用 mysql_real_escape_string 后将其添加到数据库中会将其存储在转义状态。
    • 请看我的编辑。似乎魔术引号已打开,但我无法编辑 php.ini 文件,因为它托管在 GoDaddy 上...
    • 正如我所见,他在文本框中显示转义值,然后说当他再次搜索时,它转义了转义值。但是,我可能错了。
    • @behrk2 请参阅我关于将其添加到 .htaccess 文件的说明。你应该能够做到这一点。如果您不能这样做,还有最后一个选项 - 请参阅示例 #2,us2.php.net/manual/en/security.magicquotes.disabling.php
    【解决方案2】:

    魔术引号已启用。这意味着放置在 post 或 get 或其他类似位置的任何内容都会自动转义,因此初学者不必担心它。如果我没记错的话,它在当前版本的 PHP 中已被弃用。

    您想要解决这个问题,并让脚本在任何配置中运行相同,如下所示:

    function fixinput($value){
        if (get_magic_quotes_gpc()){
          $value = stripslashes($value);
        }
    
        return mysql_real_escape_string($value);
    }
    

    您可能需要进一步修改它以将非数字数据包含在引号中,这是一种常见的变体,但我发现手动放置这些引号会更好。

    【讨论】:

      【解决方案3】:

      对 fixinput 函数稍作修改,以检查您安装的 PHP 是否确实有真正的转义字符串(旧版本没有):

        function fixinput($value){
          if (get_magic_quotes_gpc()){
            $value = stripslashes($value);
          }
      
          if (function_exists('mysql_real_escape_string')) {
            return mysql_real_escape_string($value);
          }
          else {
            return mysql_escape_string($value);
          }
        }
      

      【讨论】:

        【解决方案4】:

        我不检查 get_magic_quotes_gpc 是否打开/关闭。

        我只是做$lname = mysql_real_escape_string(stripslashes($_POST['lname']));,所以如果没有任何引用的文本,它不会去掉斜杠。如果有引用,它会去掉它们。

        它对我来说很神奇!

        【讨论】:

        • 好的,但是根据使用的文本,这可能会转换用户提交的文本。在大多数情况下,它会起作用,但不是全部。此外,可能只是您一直处于启用魔术引号的环境中,在这种情况下您不会有任何麻烦(直到您尝试将其移植到另一个环境)。
        • @kdluzni .. wtf?我写道,它对我来说是奇迹(这意味着可能不会对每个人都产生“奇迹””..我还提到我不检查 get_magic.. 因为我知道它是开启的。
        • 是的,但只是说你不检查而不解释为什么可能会导致 OP 认为某些东西总是安全的,而实际上它不是。如果您的环境适用于此,那很好,但该方法可能存在缺陷,指出它们很重要。此外,magic_quotes 已被弃用,并将从 PHP 6 中删除。那时,您的代码将停止正常工作,而检查 gpc 的代码将正常工作(直到有一天他们删除了检查功能,但听起来不就像他们计划的那样)。
        【解决方案5】:

        当它在数据库中时,它显示为 O\'Connor。

        所以,如果我要在我的网络应用程序中回忆那个姓氏,我将不得不使用:

         $lname = stripslashes($r["lname"]);
        

        错了!当您使用mysql_real_escape_string 转义字符串时,它们只会在查询中转义。数据库解释查询,因此数据最终在数据库中没有任何转义字符。从数据库中提取数据时,您不必使用stripslashes。如果你认为你这样做了,那么这意味着你的数据库中的数据被破坏了。很可能是因为您打开了魔术引号。

        你应该:

        • 全局关闭魔术引号或反转其效果。详情请见the manual
        • 要么使用bound parameters(最佳解决方案)使用mysql_real_escape_string 转义所有变量。您应该在构建查询的地方执行此操作。
        • 不要对从数据库中提取的内容执行任何操作。

        特别是,不要像fixinput 和此处某些答案中列出的变体一样创建函数。这是解决问题的错误方法,因为它会弄乱任何不是来自 http-request 的数据。

        【讨论】:

        • 仅当您在不应该使用的数据上使用它时。说在将数据发送到数据库之前不使用函数来简化数据安全,就等于说您不应该编写用于验证电话号码的函数,而应该在每次需要时手动放置该代码。或者编写任何其他函数来缩短和澄清您的代码。函数的重点是在应该使用的地方使用它,而不是在任何地方使用它。如果您最终因使用该函数而得到损坏的数据,那仅意味着您在不属于它的地方使用了它。
        • 我不同意。这是一个糟糕的抽象,因为它在同一个地方做了两个完全不同的事情。解决这个问题比用弱抽象画出来要好得多。它的名字也很糟糕,这意味着误用或混淆的可能性很高。
        • 我承认命名可能需要一些工作,但它只做一件事。它处理输入。在将数据发送到查询之前,您可以在用户有机会操作的任何数据上使用它。至于解决问题,如果可能的话,这绝对是一个更好的解决方案,但是我亲身经历了不控制主机环境带来的困难,我更喜欢编写独立于这些设置工作的代码(即使它们被禁用在我自己的系统上)。我认为它在用 C 编写时不使用仅限 Windows 或 unix 的命令/标题/库。
        • 你不需要控制 php.ini 来反转魔术引号。请参阅我上面链接到的手册。
        【解决方案6】:

        您需要做的就是获取搜索查询 mysql_real_escape_string 它,它应该完全没问题。不过,最好的方法是永远不要将其转义存储,而是将其转义,所有内容都进入数据库。

        相反,这样做:

        $_SESSION['搜索'] = $_GET['搜索']; $search = mysql_real_escape_string($_GET['search']);

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-11-13
          • 2013-12-14
          • 2013-02-16
          • 2013-08-25
          • 2011-01-23
          • 2011-06-02
          • 1970-01-01
          相关资源
          最近更新 更多