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

时间:2019-12-26 22:15:12

标签: 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"
            )
        )
    )   
)

这是函数的特定部分

case "insert":
    foreach ($tables as $instance => $inserttables) {
        foreach ($inserttables as $table => $fields) {
            // create a count on the ammount 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个微小的东西(即当我在数据库中输入多个项目)时,这一切正常。它给了我以下错误

  

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

一段时间后,我意识到是这种情况。这里的bind参数只有1个变量,我用逗号很好地分隔了所有变量(以便模仿列表)。观看这种光学眼镜可以说看起来不错,但是我认为bind参数声明确实需要单独的变量。此时,它实际上只看到一个变量,而不是我的测试用例中的4个变量。

我尝试过这种循环方式:

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

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

  

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

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

==编辑==

按要求构造表结构,尽管我怀疑这是问题所在,因为我得到的是绑定参数错误,而不是执行语句时出错。

structure of this 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']);
}

1 个答案:

答案 0 :(得分:3)

您需要将每个变量分别传递给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);

它应该可以正常工作。