遍历绑定参数中的数组 - 准备好的语句

Loop through array in bind parameters - prepared statement

我正在编写一个函数,我可以在其中执行一些数据库操作,在本例中是基于简单数组的插入数据

"insert" => array (
    "1" => array (
        "tnt_role" => array (
            "rolename" => array (
                "value" => "administrator",
                "notation" => "string"
            )
        )
    ),  
    "2" => array (
        "tnt_role" => array (
            "rolename" => array (
                "value" => "user",
                "notation" => "string"
            )
        )
    ),
    "3" => array (  
        "tnt_users" => array (
            "username" => array (
                "value" => "administrator",
                "notation" => "string"
            ),
            "userpassword" => array (
                "value" => md5('admin', FALSE),
                "notation" => "string"
            ),
            "email" => array (
                "value" => "someone@something.com",
                "notation" => "string"
            ),
            "roleid" => array (
                "value" => "1",
                "notation" => "int"
            )
        )
    )   
)

这里是函数的具体部分

case "insert":
    foreach ($tables as $instance => $inserttables) {
        foreach ($inserttables as $table => $fields) {
            // create a count on the number of fields that are being parsed
            $countfields = count($fields);
            $sql = "INSERT INTO ". $table ." (" ;
            $i = 0;
            // set up the columns for the insert statement
            foreach ($fields as $field => $value) {     
                $i++;
                $sql .= $field;
                if ($countfields != $i ) {
                    $sql .= ", ";
                }
            }
            // close the column statement, open the value statement, since this is prepared, we will add question marks and add later the values
            $sql .= ") ";
            $sql .= "VALUES (";
            $i = 0;
            $parameters = "";
            $notation = "";
            foreach ($fields as $field => $value) {     
                $i++;
                $sql .= "?";
                // set up the notation in the bind parameters
                switch($value['notation']) {
                    case "int":
                        $notation .= "i";
                        break;
                    case "string":
                        $notation .= "s"    ;
                        break;  
                }
                // need to escape the email and username values 
                $parameters .= "'".$value['value']."'" ;
                if ($countfields != $i ) {
                    $sql .= ", ";
                    $parameters .= ", ";
                }
            }
            $sql .= ")";

            $stmt = mysqli_prepare($con, $sql);
            mysqli_stmt_bind_param($stmt, $notation, $parameters);
            if(mysqli_stmt_execute($stmt)) {
                    echo "data entered";
            } else {
                echo "error in following query:". $sql; 
            }                               
        }
    }
    break;

这一切都很好,除了 1 个小问题,那就是当我在数据库中输入超过 1 个项目时。它给了我以下错误

mysqli_stmt_bind_param(): Number of elements in type definition string doesn't match number of bind variables in .... line 647

过了一会儿我意识到是参数变量。这里的绑定参数只有 1 个变量,我用逗号将它们很好地分开(为了模仿列表)。查看此光学文件会说这看起来不错,但我认为绑定参数语句确实需要单独的变量。此时它实际上只看到一个变量,而不是我的测试用例中的 4 个。

我试过这样循环:

mysqli_stmt_bind_param($stmt, $notation, 
    foreach ($fields as $field => $value) {     
        echo $value['value'];
        if ($countfields != $i ) {
            echo ",";
        }
    }
);

但是没有用,因为它会吐出以下内容。

Parse error: syntax error, unexpected 'foreach' (T_FOREACH) in

有人知道如何解决这个问题吗?

==编辑==

table 结构符合要求,虽然我怀疑是那个问题,因为我得到一个绑定参数错误,而不是执行语句时的错误。

== 编辑 2 ==

还尝试了以下方法,但没有帮助,因为它没有堆叠(我在 PDO 中看到了这个)

foreach ($fields as $field => $value) { 
    switch($value['notation']) {
        case "int":
            $notation = "i";
            break;
        case "string":
            $notation = "s" ;
            break;  
    }
    mysqli_stmt_bind_param($stmt, $notation, $value['value']);
}

您需要将每个变量单独传递给 mysqli_stmt_bind_param,因此 $parameters 需要是一个数组,而不是字符串。更改以下代码行:

$parameters = "";

至:

$parameters = array();

$parameters .= "'".$value['value']."'" ;

至:

$parameters[] = $value['value'];

(请注意,使用准备语句时无需转义值)

删除这一行:

$parameters .= ", ";

最后,改变

mysqli_stmt_bind_param($stmt, $notation, $parameters);

至:

mysqli_stmt_bind_param($stmt, $notation, ...$parameters);

它应该可以正常工作。