2010-11-23 86 views
9

在我的脑海里,下面的脚本应该工作:为什么不能将MYSQL函数传递到准备好的PDO语句中?

$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(), INTERVAL 1 MONTH))';

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

...等等...

准备的语句变成:

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

我知道这将返回相同的结果NULL,但我担心如果我简单地改变sql语句:

UPDATE表SET状态=, DATE_MODIFIED = $ VAR

? 10

我打开自己注射?

+2

准备的语句用于命令和数据的**分离**。而且你不能撤消这种分离,并将数据解释为SQL语句。 – mario 2010-11-23 18:31:38

回答

13

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

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

或者,你可以设置date_modified到一个时间戳字段,它会自动在SQL更新更新date_modified领域。

+0

@Brad - 谢谢,我已经在数据库中有另一个时间戳字段,实际的调用远远超过NOW(),但我会相应地修改 – JM4 2010-11-23 20:43:00

+0

以澄清 - 我传递一个值$变量,因为函数可以完全更改所以我仍然想在那里“可以”成为注射的情况? – JM4 2010-11-23 20:43:39

+0

那么你为什么发布该代码?你应该发布正在使用的实际代码,如果你正在传递一个变量,然后显示你正在使用的实际变量(或者至少它的例子是'NOW()'将永远不会像你一样工作),你是怎么样的在你发布的场景中使用NOW()`没有任何意义。 – 2010-11-23 21:05:53

0

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

7

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

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

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