Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用POST数据值作为参数时出现PDO错误_Php_Mysql_Pdo_Prepared Statement - Fatal编程技术网

Php 使用POST数据值作为参数时出现PDO错误

Php 使用POST数据值作为参数时出现PDO错误,php,mysql,pdo,prepared-statement,Php,Mysql,Pdo,Prepared Statement,我有一个SELECT语句,我正在通过PHP和PDO构建该语句,以提供在过去XX分钟内登录的用户列表。当我硬编码SQL语句执行的时间间隔很好,但是当我尝试替换从web表单中选择的时间间隔时,我得到了一个SQL错误。我不确定出了什么问题。我正在使用PDO和PREPARE语句 try { $sql = 'SELECT DISTINCT PlayerName FROM Player_Data pd LEFT JOIN character_data cd ON

我有一个SELECT语句,我正在通过PHP和PDO构建该语句,以提供在过去XX分钟内登录的用户列表。当我硬编码SQL语句执行的时间间隔很好,但是当我尝试替换从web表单中选择的时间间隔时,我得到了一个SQL错误。我不确定出了什么问题。我正在使用PDO和PREPARE语句

try
{
    $sql = 'SELECT DISTINCT PlayerName 
        FROM Player_Data pd LEFT JOIN character_data cd 
        ON pd.PlayerUID = cd.PlayerUID 
        WHERE cd.LastLogin > DATE_SUB(NOW(), :login_interval_value)';
    $statement = $pdo->prepare($sql);
    $statement->bindValue(':login_interval_value',$_POST['login_interval']);
    $statement->execute();
    $results = $statement->fetchAll();
}
catch (PDOException $e)
{
    $error = 'Error getting player names: ' . $e->getMessage();
    include 'error.html.php';
    exit();
}
这是我得到的错误

Error getting player names: SQLSTATE[42000]: Syntax error or access violation: 1064 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 ''INTERVAL 60 MINUTES')' at line 4

您不能将占位符用于间隔60分钟,它将引用该占位符

您只需要将该值转换为整数(而不是Post number)


两处更正。时间单位为单数(1)。另一个是,您需要将登录间隔的post数据设置为分钟数。这是完全合法的:

DATE_SUB(NOW(), INTERVAL '60' MINUTE)
这是不正确的,当post数据是整个间隔表达式时会发生这种情况:

DATE_SUB(NOW(), 'INTERVAL 60 MINUTE')
因此,要么更改表单,使$\u POST['login\u interval']只是分钟数,要么从中提取分钟数。假设您更改了表单,则代码将更改为:

try
{
    $sql = 'SELECT DISTINCT PlayerName 
        FROM Player_Data pd LEFT JOIN character_data cd 
        ON pd.PlayerUID = cd.PlayerUID 
        WHERE cd.LastLogin > DATE_SUB(NOW(), INTERVAL :login_interval_value MINUTE)';
    $statement = $pdo->prepare($sql);
    $statement->bindValue(':login_interval_value',$_POST['login_interval']);
    $statement->execute();
    $results = $statement->fetchAll();
}

1-

为什么不尝试将
$\u POST['login\u interval']
存储到另一个变量并将其分配到参数上?根据您的建议,我尝试了,但最终还是出现了相同的错误。我还想补充一点,我将添加一个检查,以确保$\u POST['login\u interval']实际上是一个数字。阅读这些文档,了解MySQL在该上下文中如何处理带引号的字符串。另一点是像xdazz指出的那样嵌入浇铸的int值。这就成功了!我没有意识到间隔的整数值可以被引用,bindValue参数也不会有单引号。我也想使用bindValue来阻止SQL注入。非常感谢你@网络蠕虫请注意,与答案本身不同的是,该评论完全具有误导性。Mysql将把一个带引号的字符串转换成一个数字,不会产生致命的后果。而像xdazz指出的那样嵌入浇铸的int值并不是一个好办法。@恐怕我不太理解你的常识。其他答案(尽管受到赞赏)似乎是动态构建SQL语句,我一直认为这是个坏主意,因此我想“准备”查询。重读后,我发现我的评论措词不当。我绝对同意答案中的方法就是这样做。当使用PDO时,使用xdazz的[完全合法]解决方案会伤害我的眼睛。MySQL可以使用裸[无引号]数字,但引用它们是更好的形式。当您使用裸数字时,MySQL仍然会将其视为字符串,并且可以做一些有趣的事情(以doc链接为例)。
try
{
    $sql = 'SELECT DISTINCT PlayerName 
        FROM Player_Data pd LEFT JOIN character_data cd 
        ON pd.PlayerUID = cd.PlayerUID 
        WHERE cd.LastLogin > DATE_SUB(NOW(), INTERVAL :login_interval_value MINUTE)';
    $statement = $pdo->prepare($sql);
    $statement->bindValue(':login_interval_value',$_POST['login_interval']);
    $statement->execute();
    $results = $statement->fetchAll();
}