1

因此,我将在使用时会发生变化的值数组传递给一个方法,然后将它们插入数据库。我的问题是绑定参数的方式。

public function insertValues($table, $cols, $values) 
{
    $mysqli = new mysqli(DBHOST, DBUSER, DBPASSWORD, DBDATABASE);

    $colString = implode(', ', $cols); // x, x, x
    $valString = implode(', ', array_fill(0, count($values), '?')); // ?, ?, ?

    $sql = "INSERT INTO $table ($colString) VALUES($valString)";
    if (!$stmt = $mysqli->prepare($sql))
         echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;

    // THIS IS THE PROBLEM AREA
    foreach ($values as $v)
        if (!$stmt->bind_param('s', $v))
            echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error;

    if (!$stmt->execute())
        echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;

    $stmt->close();
    $mysqli->close();
}

我需要一种方法来一次绑定所有参数,而不是一次绑定一个,但我想不出一种有用的方法来做到这一点。任何帮助将不胜感激。

4

2 回答 2

3

我在 PHP.net ( http://php.net/manual/en/mysqli-stmt.bind-param.php )上找到了您正在寻找的问题的答案。为方便起见,我将其粘贴在这里,所有功劳都归功于通过电子邮件 Nick9v ^ät^ hotmail -remove- -dot- com 的人

在准备语句时处理动态数量的字段值时,我发现这个类很有用。

[编者注:将 BindParam::add() 更改为通过引用接受 $value,从而防止在较新版本的 PHP 中出现警告。]

<?php 
class BindParam{ 
    private $values = array(), $types = ''; 

    public function add( $type, &$value ){ 
        $this->values[] = $value; 
        $this->types .= $type; 
    } 

    public function get(){ 
        return array_merge(array($this->types), $this->values); 
    } 
} 
?> 

用法很简单。创建一个实例并使用 add 方法进行填充。当您准备好执行时,只需使用 get 方法。

<?php 
$bindParam = new BindParam(); 
$qArray = array(); 

$use_part_1 = 1; 
$use_part_2 = 1; 
$use_part_3 = 1; 

$query = 'SELECT * FROM users WHERE '; 
if($use_part_1){ 
    $qArray[] = 'hair_color = ?'; 
    $bindParam->add('s', 'red'); 
} 
if($use_part_2){ 
    $qArray[] = 'age = ?'; 
    $bindParam->add('i', 25); 
} 
if($use_part_3){ 
    $qArray[] = 'balance = ?'; 
    $bindParam->add('d', 50.00); 
} 

$query .= implode(' OR ', $qArray); 

//call_user_func_array( array($stm, 'bind_param'), $bindParam->get()); 

echo $query . '<br/>'; 
var_dump($bindParam->get()); 
?> 

这将为您提供如下所示的结果:

SELECT * FROM users WHERE hair_color = ? 或年龄 = ? 或余额 = ? 数组(4) { [0]=> 字符串(3) "sid" 1 => 字符串(3) "red" [2]=> int(25) [3]=> float(50) }

于 2013-03-18T23:47:29.783 回答
0

该代码不起作用,因为 bind_param 必须在对函数的一次调用中包含所有查询参数,而不是对每个参数进行多次调用,它还需要通过引用传递变量,因此在 foreach 调用中它总是相同的变量与它在循环的最后一次迭代中的值。

最简单的方法是用类型和参数组成一个数组,然后通过调用 call_user_func_array 将其传递给 bind_param,例如:

$params = array();
$types = '';

foreach ($values as $k => $v)
{
    $types .= 's';
    $params[] = &$values[$k];
}

$bind_params = array_merge(array($types), $params);

if (!call_user_func_array(array($stmt, 'bind_param'), $bind_params))
    // ...

请注意, bind_param 期望变量通过引用而不是值传递,否则它将是几行构造带有值的数组,而不是 foreach 循环。

于 2013-03-19T01:06:31.670 回答