自定义mysqli类中bind_param的参数计数错误

时间:2017-11-26 13:16:50

标签: php mysqli prepared-statement

尝试使用$this->_mysqli生成自定义mysqli类/包装器作为mysqli实例:

// Query string generator
private function gen_query($type, $data, $table){
    switch ($type) {
        case 'ins':
            $query = "INSERT INTO " .$table .' ';
            $query .= implode_key($opr= ', ', $data);
            $query .= " VALUES " . value($data);
            break;
        case 'select':
            // yet to generate
        default:
            $query ='';
            break;
    }
    return $query;
}

// Generates bind parameters
private function gen_param($data){
    $_param = "'";
    foreach ($data as $v) {
        $_param .= $this->detect_type($v);
    }
    $_param .= "', ";
    foreach ($data as $k=>$v) {
        if($v == end($data)) {
            $_param .="$$k";
            continue;
        }
        $_param .= "$$k, ";
    }
  return $_param;
}

public function insert( $table, $data ){
    $table  =  $this->_prefix . $table;
    $table = $this->escape($table);
    $query = $this->gen_query('ins', $data, $table);
    $stmt = $this->_mysqli->prepare($query);
    foreach ($data as $key => $value) {
        $$key = $value;
    }
    $test = $this->gen_param($data);
    if(!$stmt->bind_param($test)) {
        echo $this->_mysqli->error;
    }
    if($stmt->execute()){
        print 'Success!'.'<br />'; 
    } else {
        die('Error : ('. $this->_mysqli->errno .') '. $this->_mysqli->error);
    }   
}

所以当用户输入

$data = [ 'first_name' => 'foo', 'last_name' => 'bar', 'another_field' => 'blah'];
$db->insert('t1', $data);

我收到此错误:

 Warning: Wrong parameter count for mysqli_stmt::bind_param() in path\to\class-db.php on line 138

这是第138行:if(!$stmt->bind_param($test))

1 个答案:

答案 0 :(得分:0)

不确定为什么问题被低估了。无论如何,我通过引用this repo来解决这个问题。

我们需要摆脱gen_param,改为使用数组并使用回调函数调用以获取正确的参数值并引用这些值。

代码现在是:

    public function insert( $table, $data ){
    $table  =  $this->_prefix . $table;
    $table = $this->escape($table);
    $this->esc_sql_arr($data);
    $query = $this->gen_query('ins', $data, $table);
    $stmt = $this->_mysqli->prepare($query);
    $this->_bind_param($data);
    call_user_func_array(array($stmt, 'bind_param'),$this->return_ref($this->bind_arr));
    if($stmt->execute()){
        echo "Success!";
    }else{
        die('Error : ('. $this->_mysqli->errno .') '. $this->_mysqli->error);
    }
    $this->reset();
}

private function _bind_param($data){
    foreach($data as $key=>$value) {
        $this->_bind_values($value);
    }
}

private function _bind_values($value) {
    $this->bind_arr[0] .= $this->detect_type($value);
    array_push($this->bind_arr, $value);
}

protected function return_ref(array &$arr)
{
    //Reference in the function arguments are required for HHVM to work
    //https://github.com/facebook/hhvm/issues/5155
    //Referenced data array is required by mysqli since PHP 5.3+
    if (strnatcmp(phpversion(), '5.3') >= 0) {
        $refs = array();
        foreach ($arr as $key => $value) {
            $refs[$key] = & $arr[$key];
        }
        return $refs;
    }
    return $arr;
}

代码远未完成,但这让我开始了。