PDO has always offered binding values to the prepared statement directly in the execute() call by providing an array with the values. The same functionality was never present in mysqli, and many users have been confused by that lack of seemingly easy functionality. (See Bug #40891, Bug #31096)
I would like to propose adding a new optional argument to mysqli_stmt::execute() same as PDO does with PDOStatement::execute(). The goal of this proposal is to simplify mysqli usage with a simple fix that does not require major refactoring.
This proposal tries to address the following mysqli limitations:
// mysqli can only bind by reference and each variable needs to be passed as a separate argument. $id = 1; $name = trim(' Dharman '); $stmt = $mysqli->prepare('INSERT INTO users(id, name) VALUES(?,?)'); $stmt->bind_param('ss', $id, $name); $stmt->execute(); // The following would fail and throw an error $stmt = $mysqli->prepare('INSERT INTO users(id, name) VALUES(?,?)'); $stmt->bind_param('ss', 1, trim(' Dharman ')); $stmt->execute(); // Binding an array can be very confusing $arr = [2,3,5,8,13]; $stmt = $mysqli->prepare('SELECT name FROM users WHERE id IN ('.str_repeat('?,', count($arr) - 1) . '?)'); $stmt->bind_param(str_repeat('s', count($arr)), ...$arr); $stmt->execute(); // SOLUTION: bind in execute // it is now possible to bind by value $stmt = $mysqli->prepare('INSERT INTO users(id, name) VALUES(?,?)'); $stmt->execute([1, trim(' Dharman ')]); // binding an array becomes less of a chore $arr = [2,3,5,8,13]; $stmt = $mysqli->prepare('SELECT name FROM users WHERE id IN ('.str_repeat('?,', count($arr) - 1) . '?)'); $stmt->execute($arr);
It also works in procedural style.
$stmt = mysqli_prepare($mysqli, 'INSERT INTO users(id, name) VALUES(?,?)'); // $stmt->execute([$id, trim(' Dharman ')]); mysqli_stmt_execute($stmt, [$id, trim(' Dharman ')]); // with the existing alias mysqli_execute($stmt, [++$id, trim(' Dharman ')]);
MySQL can type juggle as easily as PHP. The safest way to bind parameters if you are not 100% certain of their type is to bind as a string. In many cases, this is the preferred simplest way. Type specifications should only be used in rare situations when the data should be passed to MySQL with a specific type. In reality, such situations are scarce and they depend on the SQL not on PHP data type. For these rare cases, we can continue using bind_param() with the right type specification.
While the idea came from PDO bind-in-execute implementation, the mysqli proposal differs in two small ways.
Unfortunately, I am limited to Windows programming and I have no way of developing the same for libmysql and testing it myself. In theory, it should be possible to add this for libmysql with slight adjustments, but support for libmysql is not actively maintained at the moment and there are more problems that would probably need to be addressed by whoever decides to maintain libmysql support.
Classes extending mysqli_stmt::execute() will be required to specify the additional parameter now.
Next PHP 8.X (8.1)
This RFC will have no impact on any existing functionality. We would only be adding a new optional parameter to an existing function.
None
None.
The traditional way of binding variables to placeholders in mysqli remains unchanged. However, it is not possible to mix both styles in the same prepared statement as both expect all parameters to be provided in a single method call.
None, but see related RFC mysqli_execute_parameters
Simple yes/no vote.
Voting started on 2021-03-08 and ends on 2021-03-27