简体   繁体   中英

bind_param error - Number of elements in type definition string doesn't match number of bind variables

I have an array that I am preparing for a SQL query, so following the steps to make it secure as possible. Attempting the following:

First I implode the array - I want the string result to come out as 'string1','string2','string3' and so on:

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

I make my query:

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

And prepare the statement variable:

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

Then I attempt a bind_param with str_repeat, and this is where things go wrong:

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

I get:

mysqli_stmt::bind_param(): Number of elements in type definition string doesn't match number of bind variables

Does anyone know why I am getting this and how I can resolve it?

Looking at your dynamic creating of your placeholders:

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

So seem to have creating them with ' quotations. Placeholders do not need quotations.

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

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

Then, in assigning types, you don't need them quoted also:

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

Sidenote: Take note that you'll also having to dynamically call bind_param thru call_user_func_array() since you're going to use an array. This part discusses it thoroughly .

Though I'd suggest/prefer to use PDO's ->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);

Another way with using 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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM