Php MySQLi准备的语句-传递数组

Php MySQLi准备的语句-传递数组,php,mysqli,prepared-statement,Php,Mysqli,Prepared Statement,我的代码在这里遇到了一些真正的困难。我试图将一个数据数组传递给函数,并让它使用准备好的语句动态地构建一个INSERT语句 所以我有这个: public function create($data) { global $mysqli; foreach ($data as $field => $value) { $fields[] = $field; $values[] = $value;

我的代码在这里遇到了一些真正的困难。我试图将一个数据数组传递给函数,并让它使用准备好的语句动态地构建一个INSERT语句

所以我有这个:

    public function create($data) {
        global $mysqli;
        foreach ($data as $field => $value) {
            $fields[] = $field;
            $values[] = $value;
        }
        $query = "INSERT INTO " . $this->class_name . " (";
        for ($i = 0; $i < count($fields); $i++) {
            if ($i == (count($fields) - 1)) {
                $query .= "" . $fields[$i] . "";
            } else {
                $query .= "" . $fields[$i] . ", ";
            }
        }
        $query .= ") VALUES (";
        $params = array();
        for ($i = 0; $i < count($values); $i++) {
            if (is_int($values[$i])) {
                $params[] = "i";
            } else {
                $params[]= "s";
            }
            if ($i == (count($values) - 1)) {
                $query .= "?";
            } else {
                $query .= "?, ";
            }
        }
        $query .= ")";
        if ($stmt = $mysqli->prepare($query)) {
            call_user_func_array(array($stmt, "bind_param"), array_merge($params, $values));
        } else {
            die("COULD NOT CONNECT create()");
        }
        //echo $query;
    }
公共函数创建($data){
全球$mysqli;
foreach($field=>$value形式的数据){
$fields[]=$field;
$values[]=$value;
}
$query=“插入到“$this->class_name.”(“;
对于($i=0;$iprepare($query)){
调用_user_func_数组(array($stmt,“bind_param”)、array_merge($params,$values));
}否则{
die(“无法连接create()”;
}
//echo$query;
}
问题是,我不断遇到以下错误:

警告:mysqli_stmt::bind_param()的参数2应该是一个引用,第44行的E:\xampp2\htdocs\school2\application\models\CRUDAObject.php中给出了该值

我对预先准备好的语句非常陌生,但当我传递它时,我无法确定数组需要哪种格式/布局


有人能帮忙吗?

从PHP5.6开始,这变得非常简单,不需要调用用户函数数组。诀窍是对值列表使用splat(“unpack”)操作符()。向下滚动查看“短版本”,或者通读查看我如何处理SQL事务中涉及的各种数据元素

我用我写的三个函数做了三件事

  • 我创建了一个key=>value数组,其中key与MySQL列名完全匹配
  • 我创建了一个包含数据类型的字符串(例如:“ssbn”)
  • 我有一个为insert语句创建动态引用的函数
  • 在那之后,事情就很简单了

    因此,首先,基础工作:

    // This would be passed to a functionized version of this:
        // $MySQLInsertArray is an array of key=>value where key is db column name
        // $MySQLDataTypes is a list of data types used to bind, eg: 'sssdsdnb'
    
    // This creates the reference pointers for the insert statement (eg: '?,?,?,?')
        $MySQLQs=str_repeat("?,",strlen($MySQLDataTypes)-1)."?";
    
    
    
    // Make a *STRING* of the column names
        $ColumnList=implode(",",array_keys($MySQLInsertArray));
    
    // Make an *ARRAY WITH NO KEYS* of the values
        $ValueList=array_values($MySQLInsertArray);
    
    // Do all the fun SQL stuff
        $stmt = $conn->prepare("INSERT INTO ".$TBName." (".$ColumnList.") VALUES (".$MySQLQs.")");
    
    // USE THE UNPACK OPERATOR (...)
        $stmt->bind_param($MySQLDataTypes,...$ValueList);
        $stmt->execute();
    
    短版本是:

    • 构建一个列名称字符串(逗号分隔)
    • 构建一个值数组(并没有键名)——它在下面的语句中是“$ValueList”
    • 在bind_param语句中使用unpack运算符解压缩$ValueList中的值。现在就这么简单了
    这意味着,重要的部分是这三个时期:

    $stmt->bind_参数($MySQLDataTypes,..$ValueList)


    可能会帮助你。您需要创建一个引用数组,而不是直接传递现有的
    array\u merge()
    。如果您还没有完全习惯于使用MySQLi,您可以随时跳转到PDO,在那里您可以选择按引用或按值绑定。只是说…是的,像这样的事情用PDO要容易得多。看看另一篇文章,我还是不太清楚你的意思。我是否需要以不同的方式构造阵列?编辑:不完全与MySQLi结合-但是我对这个项目的修改有点限制。生成字段名的第一个循环可以简化为
    内爆(',',$fields)
    ,基本上。让你知道,splat操作符是5.6,PHP中有内爆()。