PDO查询到mysql,带有mysql列的数字名称.如何正确执行


PDO query to mysql with a numeric name for mysql column. How to execute properly

我在mysql表中有一个名为"1"的字段,这是一个数字...

我的PDO代码是:

$category = 1;
$stmt = $conn->prepare("SELECT * FROM account where :category = '1'");
$stmt->bindParam(':category', $category, PDO::PARAM_INT);
$stmt->execute(); 

它不起作用,因为在 mysql 中我必须使用:

SELECT * FROM account where `1` = '1';

而不是:

SELECT * FROM account where 1 = '1';

我怎样才能用我的PDO做到这一点?

感谢

PDO 不允许您将绑定参数用作列或表标识符,因此无法直接将:categoryprepare()/execute()一起使用并成功替换数字列名。

但是,如果可以安全地验证下拉菜单中的数字列名称以证明它在可接受的范围内并且确实是整数,那么在查询中使用变量是安全的。正如您已经知道的那样,您需要用反引号引用它。

使用ctype_digit($category)preg_match('/^'d+$/', $category)等表达式对其进行验证,并测试它是否在具有列名的整数范围内。

// Validate $cateogry
// Assuming it came from $_POST['category']
$category = isset($_POST['category']) ? $_POST['category'] : null;
// And assuming the possible range was 1 - 4
// Ensure the input value was an integer with ctype_digit()
if (ctype_digit($category) && $category >= 1 && $category <=4) {
  // Execute the query with a backtick-quoted $category
  // Since you aren't going to bind any params, you can skip the overhead of
  // prepare()/bindParam()/execute() and just call query() instead
  $result = $conn->query("SELECT * FROM account where `$category` = '1' order by rand()");
  if ($result) {
    // Fetch rows and do whatever you planned with them
    $rows = $result->fetchAll(PDO::FETCH_ASSOC);
  }
}
else {
  // Invalid value, don't perform your query, show an error, etc....
}

如果您没有安装 ctype 扩展(您可能安装了),请改用preg_match()示例。

另一种可能性是将in_array()range()一起使用,前提是您的列是按顺序命名的。我可能更喜欢这个而不是其他任何验证选项:

if (in_array($category, range(1, 4))) {
  // $category is valid - go ahead and query with it as above
} 

如评论线程中所述,如果您能够更改此列命名方案,最好这样做。这简直令人困惑。 但是,如果您接受列名的输入,它仍然不会改变您不能为其使用 PDO 参数的事实。您仍然需要根据可能的列名数组对其进行验证。