代码之家  ›  专栏  ›  技术社区  ›  AashikP

自定义mysqli类中bind\u param的参数计数错误

  •  -1
  • AashikP  · 技术社区  · 7 年前

    尝试生成自定义mysqli类/包装器 $this->_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 回复  |  直到 7 年前
        1
  •  0
  •   AashikP    7 年前

    不知道为什么这个问题被否决了。无论如何,我通过引用解决了这个问题: 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;
    }
    

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