【问题标题】:Escaping single quote in PHP when inserting into MySQL [duplicate]插入MySQL时在PHP中转义单引号[重复]
【发布时间】:2011-02-10 21:15:24
【问题描述】:

我有一个令人困惑的问题,我似乎无法理解......

我有两条 SQL 语句:

  • 首先将表单中的信息输入数据库。
  • 第二个从上面输入的数据库中获取数据,发送一封电子邮件,然后记录交易的详细信息

问题是单引号似乎仅在第二个条目上触发 MySQL 错误!第一个实例正常工作,但第二个实例触发mysql_error()

表单中数据的处理方式是否与表单中捕获的数据不同?

查询 1 - 这没有问题(并且没有转义单引号)

$result = mysql_query("INSERT INTO job_log
(order_id, supplier_id, category_id, service_id, qty_ordered, customer_id, user_id, salesperson_ref, booking_ref, booking_name, address, suburb, postcode, state_id, region_id, email, phone, phone2, mobile, delivery_date, stock_taken, special_instructions, cost_price, cost_price_gst, sell_price, sell_price_gst, ext_sell_price, retail_customer, created, modified, log_status_id)
VALUES
('$order_id', '$supplier_id', '$category_id', '{$value['id']}', '{$value['qty']}', '$customer_id', '$user_id', '$salesperson_ref', '$booking_ref', '$booking_name', '$address', '$suburb', '$postcode', '$state_id', '$region_id', '$email', '$phone', '$phone2', '$mobile', STR_TO_DATE('$delivery_date', '%d/%m/%Y'), '$stock_taken', '$special_instructions', '$cost_price', '$cost_price_gst', '$sell_price', '$sell_price_gst', '$ext_sell_price', '$retail_customer', '".date('Y-m-d H:i:s', time())."', '".date('Y-m-d H:i:s', time())."', '1')");

查询 2 - 输入带单引号的名称时失败(例如,O'Brien

$query = mysql_query("INSERT INTO message_log
(order_id, timestamp, message_type, email_from, supplier_id, primary_contact, secondary_contact, subject, message_content, status)
VALUES
('$order_id', '".date('Y-m-d H:i:s', time())."', '$email', '$from', '$row->supplier_id', '$row->primary_email' ,'$row->secondary_email', '$subject', '$message_content', '1')");

【问题讨论】:

    标签: php mysql insert escaping


    【解决方案1】:

    您应该使用 mysql_real_escape_string() 转义每个字符串(在两个 sn-ps 中)。

    http://us3.php.net/mysql-real-escape-string

    您的两个查询行为不同的原因可能是因为您打开了magic_quotes_gpc(您应该知道这是一个坏主意)。这意味着从 $_GET、$_POST 和 $_COOKIES 收集的字符串会为您转义(即"O'Brien" -> "O\'Brien")。

    一旦您存储数据并随后再次检索它,您从数据库中返回的字符串将不会自动为您转义。你会回复"O'Brien"。因此,您需要将其传递给mysql_real_escape_string()

    【讨论】:

    • 是的,好的,感谢您提供正确编码的课程,但这并不能回答为什么两个查询不会引发相同错误的问题......
    • 我不是在寻找如何解决它的答案——我知道如何解决它。我正在寻找“为什么”!
    • 这不是正确编码的问题,而是一个巨大而危险的安全漏洞问题。话虽如此,我将在我的原始答案中添加一个 sn-p 来说明根本问题。我会在这里做,但格式会很不稳定。 :)
    • @hairdresser,为什么会在那里。这是因为您使用了魔术引号。
    【解决方案2】:

    对于任何在 2015 年找到此解决方案并继续前进的人...

    mysql_real_escape_string() 函数自 PHP 5.5.0 起已弃用。

    见:php.net

    警告

    此扩展自 PHP 5.5.0 起已弃用,将来将被删除。相反,应该使用 MySQLi 或 PDO_MySQL 扩展。另请参阅 MySQL:选择 API 指南和相关的常见问题解答以获取更多信息。此功能的替代方案包括:

    mysqli_real_escape_string()

    PDO::quote()

    【讨论】:

    【解决方案3】:

    你应该做这样的事情来帮助你调试

    $sql = "insert into blah values ('$myVar')";
    echo $sql;
    

    您可能会发现单引号在工作查询中被反斜杠转义。这可能是 PHP 通过 magic_quotes_gpc 设置自动完成的,或者您可能在代码的其他部分中自己完成了(addslashes 和 stripslashes 可能是要查找的函数)。

    Magic Quotes

    【讨论】:

    • Magic Quotes 现在说 “此功能已从 PHP 5.3.0 起弃用,并从 PHP 5.4.0 起删除。”
    • 小心! 这个答案总是有问题,现在你甚至不能再启用魔术引号了,因为即使是 PHP 语言开发人员最终也同意它是一个愚蠢的想法。所有的注入攻击都是由不正确的编码引起的,所有的编码都依赖于上下文。需要参考的用户输入,例如列名必须使用与用户输入不同的编码,该编码应该是 SQL 字符串值的一部分。魔术引用的东西假设一个上下文对所有事情都可以,这显然是一个不安全的假设。我认为这个答案应该被删除。
    【解决方案4】:

    你有几件事在你的弦上打架。

    • 缺少正确的 MySQL 引用 (mysql_real_escape_string())
    • 潜在的自动“魔术报价”——检查您的 gpc_magic_quotes 设置
    • 嵌入字符串变量,这意味着你必须知道 PHP 如何正确找到变量

    第一个查询的参数中也可能不存在单引号值。毕竟,您的示例是一个专有名称,并且似乎只有第二个查询处理的是名称。

    【讨论】:

      【解决方案5】:

      您可以执行以下操作来转义 PHP 和 MySQL。

      <?
      $text = '<a href="javascript:window.open(\\\'http://www.google.com\\\');"></a>';
      ?> 
      

      这会将 MySQL 反映为

      <a href="javascript:window.open('http://www.google.com');"></a>
      

      它是如何工作的?

      我们知道 PHP 和 MySQL 的撇号都可以用反斜杠和撇号转义。

      \'
      

      因为我们使用 PHP 插入 MySQL,我们需要 PHP 仍然将反斜杠写入 MySQL,以便它也可以转义它。 所以我们使用反斜杠反斜杠的PHP转义字符和反斜杠撇号来实现这一点。

      \\\'
      

      【讨论】:

        【解决方案6】:

        您应该只在“mysql_real_escape_string(trim($val))”中传递变量(或数据)

        $val 是困扰您的数据。

        【讨论】:

          【解决方案7】:

          我遇到了同样的问题,我是这样解决的:

          $text = str_replace("'", "\'", $YourContent);
          

          可能有更好的方法来做到这一点,但它对我有用,它也应该对你有用。

          【讨论】:

          • 有一个更好的方法......除此之外的任何其他方法。说真的,如果您不希望您的数据库获得 Bobby Table'd,请不要这样做。使用 PDO(正确的方式)——它会为您处理转义。甚至使用已弃用的mysql_real_escape_string(不是正确的方法)!或addslashes(不是正确的方式)。除此以外的任何东西。
          • 您应该为此目的执行本机功能。
          • 鲍比桌:xkcd 327
          • 这不应该被否决,因为它不是“错误的”
          【解决方案8】:

          mysql_real_escape_string() 或 str_replace() 函数将帮助您解决问题。

          http://phptutorial.co.in/php-echo-print/

          猜你喜欢
          • 1970-01-01
          • 2012-09-01
          • 2018-08-18
          • 2011-05-23
          • 2011-02-05
          • 1970-01-01
          • 2012-12-11
          • 1970-01-01
          • 2011-07-20
          相关资源
          最近更新 更多