bind_param error - 类型定义字符串中的元素数与绑定变量数

时间:2015-05-21 03:30:41

标签: php mysql mysqli

我有一个数组,我正在准备SQL查询,所以按照步骤使其尽可能安全。试图以下:

首先我破坏了数组 - 我希望字符串结果以“string1”,“string2”,“string3”等形式出现:

$in = "'" . implode("','", array_fill(0, count($finalArray), '?')) . "'";

我的查询:

$query = <<<SQL
UPDATE products SET `Status` = 'Reserved' WHERE `SerialNumber` in ($in);
SQL;
$query = <<<SQL

准备语句变量:

$statement = $mysqli->prepare($query);

然后我尝试使用str_repeat的bind_param,这就是出错的地方:

$statement->bind_param(str_repeat('\'s\',', count($finalArray)), ...$finalArray);

我明白了:

  

mysqli_stmt :: bind_param():类型定义字符串中的元素数与绑定变量数不匹配

有谁知道我为什么会这样做以及如何解决它?

1 个答案:

答案 0 :(得分:1)

查看动态创建占位符:

$in = "'" . implode("','", array_fill(0, count($finalArray), '?')) . "'";

所以好像用'语录来创建它们。占位符不需要引用。

$in = implode(',', array_fill(0, count($finalArray), '?'));

$query = "UPDATE products SET Status = 'Reserved' WHERE SerialNumber IN ($in)";
$statement = $mysqli->prepare($query);

然后,在分配类型时,您也不需要引用它们:

$statement->bind_param(str_repeat('s', count($finalArray)), $finalArray);

旁注:请注意,由于您要使用数组,因此您还必须动态调用bind_paramcall_user_func_array()。这部分讨论了它thoroughly

虽然我建议/更喜欢使用PDO&#39; ->execute()

$pdo = new PDO('mysql:host=localhost;dbname=DATABASE NAME', 'username', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$in = implode(',', array_fill(0, count($finalArray), '?'));
$query = "UPDATE products SET Status = 'Reserved' WHERE SerialNumber IN ($in)";
$statement = $pdo->prepare($query);
$statement->execute($finalArray);

使用Reflection的另一种方式:

$in = implode(',', array_fill(0, count($finalArray), '?'));
$type = str_repeat('s', count($finalArray));
$query = "UPDATE products SET Status = 'Reserved' WHERE SerialNumber IN ($in)";
$statement = $mysqli->prepare($query);

$ref = new ReflectionClass('mysqli_stmt');
$method = $ref->getMethod('bind_param');
array_unshift($finalArray, $type); // prepend the 'sss' inside
$method->invokeArgs($statement, $finalArray);

$statement->execute();