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

Dor*_*lla 1 php mysqli 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"
            )
        )
    )   
)
Run Code Online (Sandbox Code Playgroud)

这是函数的具体部分

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;
Run Code Online (Sandbox Code Playgroud)

除了一件小事,即当我在数据库中输入超过 1 项时,这一切都很好。它给了我以下错误

mysqli_stmt_bind_param():类型定义字符串中的元素数量与 .... 第 647 行中的绑定变量数量不匹配

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

我尝试这样循环它:

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

但无济于事,因为它会吐出以下内容。

解析错误:语法错误,意外的“foreach”(T_FOREACH)

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

==编辑==

表结构符合要求,尽管我怀疑这是这个问题,因为我收到绑定参数错误,而不是执行语句时出现错误。

该表的结构

==编辑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']);
}
Run Code Online (Sandbox Code Playgroud)

Nic*_*ick 5

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

$parameters = "";
Run Code Online (Sandbox Code Playgroud)

到:

$parameters = array();
Run Code Online (Sandbox Code Playgroud)

$parameters .= "'".$value['value']."'" ;
Run Code Online (Sandbox Code Playgroud)

到:

$parameters[] = $value['value'];
Run Code Online (Sandbox Code Playgroud)

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

删除这一行:

$parameters .= ", ";
Run Code Online (Sandbox Code Playgroud)

最后,改变

mysqli_stmt_bind_param($stmt, $notation, $parameters);
Run Code Online (Sandbox Code Playgroud)

到:

mysqli_stmt_bind_param($stmt, $notation, ...$parameters);
Run Code Online (Sandbox Code Playgroud)

它应该工作正常。