【问题标题】:Invalid parameter number: number of bound variables does not match number of tokens PDO insert无效的参数号:绑定变量的数量与 PDO 插入的令牌数量不匹配
【发布时间】:2013-08-08 07:59:37
【问题描述】:
function mysql_insert($data_array){
    $sql = "insert into `". $this->table_name. '`';

    $array_keys = array_keys($data_array);
    $array_keys_comma = implode(",\n", preg_replace('/^(.*?)$/', "`$1`", $array_keys));

    for($a=0,$b=count($data_array); $a<$b; $a++){ $question_marks .="?,";  }

    $array_values = array_values($data_array);
    $array_values_comma = implode(",", $array_values);

    $sql.= " ($array_keys_comma) ";
    $sql.= " values(". substr($question_marks, 0,-1) .")";

    $prepare = $this->connDB->prepare($sql);
    $insert = $prepare->execute(array($array_values_comma));

}

我想创建这样的通用函数,$data_array-来自 $_POST 此功能适用于所有形式。但我不知道我错了什么:S

【问题讨论】:

    标签: pdo insert


    【解决方案1】:

    我不知道自己哪里错了

    这很容易知道:number of bound variables does not match number of tokens.

    我想创建这样的通用函数,$data_array-来自$_POST

    给你:Insert/update helper function using PDO

    【讨论】:

    • 我刚刚删除了 id 列,现在可以了,但我应该使用 id 列,我该怎么办?
    • 不知道你在说什么 id 以及为什么你需要插入,但你可以看到一个不易受 SQL 注入攻击的工作代码(与你的相反)
    【解决方案2】:

    $array_values_comma 是 implode() 数组后的标量。所以你总是将一个元素的数组传递给你的 execute() 函数。你应该传递 $array_values。

    下面是我如何编写这个函数:

    function mysql_insert($data_array){
        $columns = array_keys($data_array);
        $column_list_delimited = implode(",", 
          array_map(function ($name) { return "`$name`"; }, $columns));
    
        $question_marks = implode(",", array_fill(1, count($data_array), "?"));
    
        $sql = "insert into `{$this->table_name}` ($column_list_delimited) 
          values ($question_marks)";
    
        // always check for these functions returning FALSE, which indicates an error
        // or alternatively set the PDO attribute to use exceptions
    
        $prepare = $this->connDB->prepare($sql);
        if ($prepare === false) {
          trigger_error(print_r($this->connDB->errorInfo(),true), E_USER_ERROR);
        }
    
        $insert = $prepare->execute(array_values($data_array));    
        if ($insert === false) {
          trigger_error(print_r($prepare->errorInfo(),true), E_USER_ERROR);
        }
    
    }
    

    进一步的改进是对$this-&gt;table_name$data_array 的键进行一些验证,以便您知道它们与现有表及其列匹配。

    有关验证列名的示例,请参阅 my answer to escaping column name with PDO

    【讨论】:

    • 这个函数容易通过标识符进行SQL注入。你不需要检查 PDO 函数,但让它们抛出异常
    • @YourCommonSense,这就是我建议验证表名和列名的原因。我确实提到了使用异常的选项,但并不是所有的 PHP 开发人员都喜欢使用异常。否决这个答案是没有根据的。
    • 这就是为什么我的其他答案使用 whitelisting 方法(注意强制性的$fields 参数)因此无懈可击
    猜你喜欢
    • 2023-03-20
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    • 1970-01-01
    • 2014-03-15
    相关资源
    最近更新 更多