【问题标题】:How to select from a dynamic column through a variable with PDO?如何通过带有 PDO 的变量从动态列中进行选择?
【发布时间】:2017-11-03 21:49:57
【问题描述】:

我有一个带有列名的 PHP 变量 $col。我想用 PDO 创建一个查询,它选择该列的值。我知道如何使用bindValue(),并尝试了以下方法:

$db = new PDO('mysql:host='. $db_host . ';dbname=' . $db_name . ';charset=utf8', $db_user, $db_password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

function get_user($id, $column){

    $sql = "
        SELECT :col
        FROM users
        WHERE `id` = :id;";

    try {
        $st = $db->prepare($sql);
        $st->bindValue('col', $column, PDO::PARAM_STR);
        $st->bindValue(':id', $id, PDO::PARAM_INT);
        $st->execute();
        $result = $st->fetch();
        return $result;
    } catch (PDOException $e) {
        echo "Database query exception: " . $e->getMessage();
        return false;
    }
}

这会导致以下异常:Database query exception: SQLSTATE[42S22]: Column not found: 1054 Unknown column ''name'' in 'field list' for $col = 'name'。当然,name 列确实存在。

它在WHERE = :value 上运行良好,但我无法让它在列中运行。如何做到这一点?

补充:我确实找到了函数bindColumn(),但我认为相反,将列名绑定到PHP变量而不是将变量绑定到列。

【问题讨论】:

  • (抱歉,我无法正确地用反引号标记代码块。)
  • 您不能通过参数绑定来执行此操作 - 原因请参见 this answer。您将需要清理该列名称并将其手动添加到查询中。
  • 不可能。占位符只能代表查询中的 VALUES,而不能代表列或字段名。您将不得不使用古老的 sql-injection-vulnerable SELECT $field FROM $table-type 字符串构造方法

标签: php mysql pdo


【解决方案1】:

您可以使用一组允许的列名来清理查询。

$allowed_columns = array('name', 'type1',etc);//Array of allowed columns to sanatise query 

然后检查列名是否在数组中。

if (in_array($column, $allowed_columns)){
      $result= get_user($id, $column);
}
function get_user($id, $column){

    $sql = "
        SELECT $column
        FROM users
        WHERE `id` = :id;";

    try {
        $st = $db->prepare($sql);
        $st->bindValue(':id', $id, PDO::PARAM_INT);
        $st->execute();
        $result = $st->fetch();
        return $result;
    } catch (PDOException $e) {
        echo "Database query exception: " . $e->getMessage();
        return false;
    }
}

【讨论】:

    【解决方案2】:

    我会使用 array_intersect 类似清理功能的东西,它只会提取允许的字段。示例:

    function get_fields_allowed($input_fields,$allowed){
      $input_fields=explode(",",$input_fields);
      $allowed=explode(",",$allowed);
      return array_intersect($allowed,$input_fields);
    }
    
    
    $select_fields=$_POST["fields"];  //example: "id,name,email"
    
    $fields=get_fields_allowed ($select_fields, "id,name" ) ;
    

    所以你然后使用 $fields 如下:

    $sql="Select $fields FROM [table] WHERE id=:id etc...";
    

    【讨论】:

    • 这很简单,但不使用 PDO。
    • @BasC 是的,您可以使用 PDO。这仅指 $fields ,因为您只允许在那里列出的“cols”,因此它是安全的。字符串的另一部分(例如 Where id=:id)可以来自用户输入,您仍然可以使用您喜欢的任何内容来组成自己。
    • @BasC 没有可以使用 PDO 的解决方案。去图吧。
    猜你喜欢
    • 2019-09-06
    • 2016-03-08
    • 2012-08-02
    • 2023-02-24
    • 2022-08-04
    • 1970-01-01
    • 2012-07-08
    • 2021-08-29
    • 2022-01-14
    相关资源
    最近更新 更多