1

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?

1 Answer 1

1

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();
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.