【问题标题】:Why cant you pass MYSQL functions into prepared PDO statements?为什么不能将 MYSQL 函数传递到准备好的 PDO 语句中?
【发布时间】:2011-05-14 15:25:05
【问题描述】:

在我看来,以下脚本应该可以工作:

$stmt = $db->prepare("UPDATE table SET status = ?, date_modified = ?");
$stmt->execute(array(1, 'NOW()'));

但是当将NOW() 传递到准备好的语句中时,什么也没有发生。用实际日期(即 2010-11-23)替换 NOW() 就可以了。

我无法在网上找到解释。有什么想法吗?

编辑

为了进一步澄清和消除问题中的任何混淆,我想将一个变量实际传递到准备好的语句中,但是,该变量将设置为 mysql 的五个可能的日期/时间函数之一。

例如

$var = 'NOW()';

$var = 'LAST_DAY(DATE_ADD(CURDATE(), 间隔 1 个月))';

$var = 'LAST_DAY(CURDATE())';

...等等...

准备好的语句变成:

$stmt->execute(array(1, $var));

我知道这将返回相同的 NULL 结果,但我担心如果我只是将 sql 语句更改为:

UPDATE 表 SET 状态 = ?, date_modified = $var

我打开自己注射?

【问题讨论】:

  • 预处理语句用于命令和数据的分离。而且您无法撤消这种分离并将数据解释为 SQL 语句。

标签: php mysql pdo prepared-statement


【解决方案1】:

准备好的语句将您插入其中的所有内容解释为文字字符串。这是为了防止任何类型的不可预测的 SQL 注入。

实际发生的情况是NOW() 正试图在读取时插入数据库(字面意思是NOW()),而不是获取要插入的实际日期。然后它可能在您的数据库中显示为空白,因为您有一个日期列,它不会将 NOW() 解释为日期,因此不接受它。

如果可能,您应该尝试在不使用任何替换方法的情况下执行 SQL,因为这种方法没有任何危险。

【讨论】:

  • 谢谢,请参阅下面布拉德的评论。我“实际上”传递的变量可能会改变并且可能仍然容易被注入?
  • 如果您的所有$var 值都是在您的 PHP 脚本中设置的,而不是任何外部源,那么您不必担心任何类型的注入。
【解决方案2】:

我的猜测是 PDO 假设 'NOW()' 是一个字符串,并在填充查询参数时将其括在引号中。我将使用 PHP 函数 date('Y-m-d') 传递当前日期,这将为您提供相同的结果。

【讨论】:

    【解决方案3】:

    您不需要将NOW() 作为参数传递,因为它是一个内置的 SQL 函数,因此无需对其进行任何处理,因此只需将其包含在实际查询中,如下所示。

    $stmt = $db->prepare("UPDATE table SET status = ?, date_modified = NOW()");
    

    或者,您可以将 date_modified 设置为 TIMESTAMP 字段,它会在 SQL 更新时自动更新 date_modified 字段。

    【讨论】:

    • @Brad - 谢谢,我已经在数据库中有另一个时间戳字段,实际调用不仅仅是 NOW(),但我会相应地修改
    • 澄清一下 - 我正在传递一个值 $variable 因为函数可以完全改变所以我仍然认为“可能”是注入的情况?
    • 那你为什么要发布那个代码?您应该发布正在使用的实际代码,如果您将其传递给变量,然后显示您正在使用的实际变量(或者至少作为 NOW() 的示例将永远不会像您拥有的那样工作),您如何使用 @您发布的场景中的 987654326@ 没有任何意义。
    • @Brad F Jacobs - 无论我发布什么功能,当它们都与时间相关时,逻辑都是完全相同的。一个函数将使用 NOW(),而另外两个日期时间字段则不会。变量设置为等于 NOW() 或其他函数,所以,是的,我的代码和问题仍然有效。
    • @JM4 在更新的版本中,$var 究竟来自哪里?它是硬编码的还是来自未知来源(POST / COOKIE / GET)?如果它是硬编码的,你就不容易受到 SQL 注入的攻击。如果它来自未知来源,那么您唯一的其他选择是使用某种类型的验证方法来验证它或删除任何不必要的字符,即:'":\/ 等,您不会期望看到查询,通过正则表达式或类似方法。
    猜你喜欢
    • 1970-01-01
    • 2014-07-20
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 2020-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多