MySQLi准备语句 - 传递数组

问题描述 投票:0回答:1

我的代码在这里遇到了一些真正的困难。我正在尝试将数据数组传递给函数,并使用预处理语句动态构建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;
    }

问题是我一直收到以下错误:

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

我对准备好的语句很新,但是当我传递它时,我无法确定数组需要的格式/布局。

有人可以帮忙吗?

php mysqli prepared-statement
1个回答
0
投票

从PHP 5.6开始,这变得非常简单,无需call_user_func_array。诀窍是使用splat(“unpack”)运算符(...)作为值列表。向下滚动“The Short Version”或者随意阅读以了解我如何处理SQL事务中涉及的各种数据元素。

我做了三件事,使用了我编写的三个函数。

  1. 我创建了一个key => value数组,其中键与MySQL列名完全匹配。
  2. 我创建了一个包含数据类型的字符串(例如:'ssssdssbn')。
  3. 我有一个函数,为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_param($ MySQLDataTypes,... $值列表);

© www.soinside.com 2019 - 2024. All rights reserved.