Ошибка PDO при использовании значения POST data в качестве параметра



У меня есть инструкция SELECT, которую я создаю с помощью PHP и PDO, чтобы предоставить список пользователей, которые вошли в систему за последние 20 минут. Когда я жестко кодирую интервал времени, оператор SQL выполняет нормально, но когда я пытаюсь заменить интервал, выбранный из веб-формы, я получаю ошибку 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
667   2  

2 ответов:

Две поправки. Единица времени является сингулярной(1). Другой заключается в том, что вам нужно, чтобы ваши пост-данные для login_interval были просто количеством минут. Это совершенно законно:

DATE_SUB(NOW(), INTERVAL '60' MINUTE)

Это неверно, и это то, что происходит, когда ваши данные поста являются выражением всего интервала:

DATE_SUB(NOW(), 'INTERVAL 60 MINUTE')

Поэтому либо измените свою форму так, чтобы $_POST['login_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 - https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add

Вы не можете использовать заполнитель для INTERVAL 60 MINUTES, он будет цитировать его.

Вам просто нужно привести значение в целое число.(Вместо номера поста.)

$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 '.(int)$_POST['login_interval'].' MINUTES)';
$statement = $pdo->prepare($sql);
$statement->execute();
$results = $statement->fetchAll();

Comments

    Ничего не найдено.