如何在 PHP PDO 查询中插入“now() -interval '2 minutes'”之类的内容?
Posted
技术标签:
【中文标题】如何在 PHP PDO 查询中插入“now() -interval \'2 minutes\'”之类的内容?【英文标题】:How to insert things like "now() -interval '2 minutes'" into PHP PDO query?如何在 PHP PDO 查询中插入“now() -interval '2 minutes'”之类的内容? 【发布时间】:2013-01-06 02:33:36 【问题描述】:我有这样的查询:(在 Postgresql 8.4 上,php-fpm 5.3.10 (fpm-fcgi))
select * from users where now() - interval '2 minutes' < seenlast ORDER BY seenlast;
我想使用 PHP/PDO 查询,所以:
$mymin=5; //this is a variable can be changed by $_GET
$query = $db_conn->prepare("select * from users where now() - interval ':myminute minutes' < seenlast ORDER BY seenlast");
$query->bindParm(":myminute",$mymin)
$query->execute;
这不起作用,我找不到以适当方式通过分钟($mymin) 的方法。如果我对时间进行硬编码,一切正常,那么代码的另一部分必须是正确的。
我也试过了:
$temp=$mymin." minutes";
$query = $db_conn->prepare("select * from users where now() - interval :myminute < seenlast ORDER BY seenlast");
$query->bindParm(":myminute",$temp)
I already saw this, didn't help
【问题讨论】:
我遇到了同样的问题,但收到了错误:SQLSTATE[HY105]: Invalid parameter type: 7
。这是因为在使用未命名参数时,我的参数比检测到的替换(问号)多。
【参考方案1】:
区间可以乘以数字。所以解决这个问题的一种方法是准备声明interval '1 minute' * :myminutes
,而不是将“myminutes”参数作为一个简单的整数传递。
【讨论】:
【参考方案2】:我不太了解 PDO 或 PHP,但我想我知道这里出了什么问题。
当你这样说时:
interval '3 minutes'
您实际上执行的转换操作与以下内容相同:
'3 minutes'::interval
cast('3 minutes' as interval)
因此,您正在做的是将 TEXT 值转换为 INTERVAL。这意味着您需要生成类似于字符串'3 minutes'
的内容。您可以使用字符串连接将字符串片段粘贴在一起:
# Use cast to make the precedence cleaner.
$query = $db_conn->prepare("select * from users where now() - cast(:myminute || ' minutes' as interval) < seenlast ORDER BY seenlast");
$query->bindParm(":myminute", $mymin)
或者你应该能够在 PHP 中进行字符串整理:
$query = $db_conn->prepare("select * from users where now() - interval :myminute < seenlast ORDER BY seenlast");
$query->bindParm(":myminute", $mymin . ' minutes')
【讨论】:
辛苦了一天,明天我也去看看。【参考方案3】:我已经为 Phalcon 及其内部 Models PDO 解析器苦苦挣扎了几个小时,遇到了同样的问题。
我找到了这个解决方案:
public static function getTimedoutRequests($secsThreshold)
return self::find(
array(
// PDO is buggy here, can't use INTERVAL
"DATE_PART('epoch', create_time) < DATE_PART('epoch', NOW()) - ?0",
"bind" => array(
$secsThreshold
)
)
);
【讨论】:
【参考方案4】:... - INTERVAL :myminute MINUTES ...
不带引号是正确的方法。如果有帮助,请将占位符视为使用老式的基于变量的查询构建方法的等价物
... - INTERVAL $myminute MINUTES
除了占位符处理变量不处理的注入漏洞。仅仅因为您使用占位符并不意味着您可以更改 SQL 语法,所以
... - INTERVAL '2 minutes'
... - INTERVAL ':myminute minute'
不是有效的 SQL。
mu 的跟进:
mysql> select now() + interval '2 minute';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
mysql> select now() + interval 2 minute;
+---------------------------+
| now() + interval 2 minute |
+---------------------------+
| 2013-01-22 13:38:24 |
+---------------------------+
1 row in set (0.02 sec)
【讨论】:
我怀疑INTERVAL :myminute MINUTES
会起作用,我希望这会产生语法错误。 INTERVAL '2 minutes'
OTOH 很好; interval '3 minutes'
是一个强制转换操作,是 '3 minutes'::interval
或 cast('3 minutes' as interval)
的另一种写法。
@MarcB:不过,问题是关于 postgresql,在这种情况下 muistooshort 是正确的。以上是关于如何在 PHP PDO 查询中插入“now() -interval '2 minutes'”之类的内容?的主要内容,如果未能解决你的问题,请参考以下文章