在MYSQLI中插入未指定长度的数组

时间:2016-11-28 11:07:17

标签: php mysqli

它远非完美,但我尝试使用MySQLI创建一个将数据插入SQL表的函数。我想创建一个通用函数,在不同的数据库中插入不同类型的数据。到目前为止,我有以下内容:

/**
 * Add data to specified table. Data consist of column name as key, and value.
 * Table is a string of the table to insert into.
 * @param array $data
 * @param string $table
 * @return string
 */
private function insert( $data = array(), $table = null ){

    foreach( $data as $key => $value ){

        // Create arrays of separate keys and values
        $keys[]     = $key;
        $values[]   = $value;

        // Get type of data
        switch( gettype( $value ) ){
            case "integer":
                $types[]    = "i";
                break;
            case "string":
                $types[]    = "s";
                break;
            default:
                $types[]    = "i";
                break;
        };

        // for each variable, add a questionmark
        $vars[]     = "?";

    }

    // Create strings out of the data
    $key    = implode( ",", $keys );
    $var    = implode( ",", $vars );
    $type   = implode( "", $types );
    $value  = '"' . implode( '\", \"', $values ) . '"';

    // prepare SQL statement
    // var_dump( $sql ) = 'INSERT INTO table (var1,var2,var3) VALUES (?,?,?)'
    $sql = "INSERT INTO " . $table . " (" . $key . ") VALUES (" . $var . ")";

    // Prepare SQL insert
    // $this->conn = new mysqli($this->server, $this->user, $this->pass, $this->name);
    if( ! ( $stmt = $this->conn->prepare( $sql ) ) ) {
        return "Preparing failed!: (" . $this->conn->errno . ") " . $this->conn->error;
    }

    // Bind parameters. THIS IS WHERE THE ISSUE IS!
    if( ! $stmt->bind_param( $type, $values ) ) {
        return "Binding failed! (" . $stmt->errno . ") " . $stmt->error;;
    }

    // Execute the statement
    if( ! $stmt->execute() ){
        return "Executing failed! (" . $stmt->errno . ") " . $stmt->error;;
    }

}

问题在于绑定参数。我无法找到绑定它们的好方法,因为我已经使用值和键获得了多个变量,但它们全部采用数组格式,并且bind_param需要一个新变量for每个

简而言之,我正在寻找一种方法,将一个未指定长度的数组添加到我的SQL中(以安全的方式,当然)。

2 个答案:

答案 0 :(得分:3)

如果您使用的是php 5.6+,则可以使用...运算符来解压缩数组。

在你的例子中:

$stmt->bind_param( $type, ...$values )

参见manual中的示例#14。

答案 1 :(得分:1)

/* Bind parameters. Types: s = string, i = integer, d = double,  b = blob */
$a_params = array();

$param_type = '';
$n = count($a_param_type);
for($i = 0; $i < $n; $i++) {
  $param_type .= $a_param_type[$i];
}

/* with call_user_func_array, array params must be passed by reference */
$a_params[] = & $param_type;

for($i = 0; $i < $n; $i++) {
  /* with call_user_func_array, array params must be passed by reference */
  $a_params[] = & $a_bind_params[$i];
}

/* Prepare statement */
$stmt = $conn->prepare($sql);
if($stmt === false) {
  trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->errno . ' ' . $conn->error, E_USER_ERROR);
}

/* use call_user_func_array, as $stmt->bind_param('s', $param); does not accept params array */
call_user_func_array(array($stmt, 'bind_param'), $a_params);

/* Execute statement */
$stmt->execute();

/* Fetch result to array */
$res = $stmt->get_result();
while($row = $res->fetch_array(MYSQLI_ASSOC)) {
  array_push($a_data, $row);
}

参考:http://www.pontikis.net/blog/dynamically-bind_param-array-mysqli