From 2c1236199247d2a0f8c27bca3cec1163c7a4c257 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Sun, 31 Jul 2022 08:43:41 -0700 Subject: [PATCH] Deprecate passing parameters to Statement::execute*() --- UPGRADE.md | 7 +++++++ src/Connection.php | 23 ++++++++--------------- src/Driver/IBMDB2/Statement.php | 10 ++++++++++ src/Driver/Mysqli/Statement.php | 10 ++++++++++ src/Driver/OCI8/Statement.php | 8 ++++++++ src/Driver/PDO/SQLSrv/Connection.php | 8 ++++++-- src/Driver/PDO/Statement.php | 9 +++++++++ src/Driver/SQLSrv/Statement.php | 8 ++++++++ src/Statement.php | 18 ++++++++++++++++++ tests/Functional/ExceptionTest.php | 5 +++++ 10 files changed, 89 insertions(+), 17 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 73d189c148c..07a55085d01 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -8,6 +8,13 @@ awareness about deprecated code. # Upgrade to 3.4 +## Deprecated passing `$params` to `Statement::execute*()` methods. + +Passing `$params` to the driver-level `Statement::execute()` and the wrapper-level `Statement::executeQuery()` +and `Statement::executeStatement()` methods has been deprecated. + +Bind parameters using `Statement::bindParam()` or `Statement::bindValue()` instead. + ## Deprecated `QueryBuilder` methods and constants. 1. The `QueryBuilder::getState()` method has been deprecated as the builder state is an internal concern. diff --git a/src/Connection.php b/src/Connection.php index a85acbca446..67530dadca0 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -1021,12 +1021,10 @@ public function executeQuery( } $stmt = $connection->prepare($sql); - if (count($types) > 0) { - $this->_bindTypedValues($stmt, $params, $types); - $result = $stmt->execute(); - } else { - $result = $stmt->execute($params); - } + + $this->bindParameters($stmt, $params, $types); + + $result = $stmt->execute(); } else { $result = $connection->query($sql); } @@ -1128,15 +1126,10 @@ public function executeStatement($sql, array $params = [], array $types = []) $stmt = $connection->prepare($sql); - if (count($types) > 0) { - $this->_bindTypedValues($stmt, $params, $types); - - $result = $stmt->execute(); - } else { - $result = $stmt->execute($params); - } + $this->bindParameters($stmt, $params, $types); - return $result->rowCount(); + return $stmt->execute() + ->rowCount(); } return $connection->exec($sql); @@ -1668,7 +1661,7 @@ public function convertToPHPValue($value, $type) * * @throws Exception */ - private function _bindTypedValues(DriverStatement $stmt, array $params, array $types): void + private function bindParameters(DriverStatement $stmt, array $params, array $types): void { // Check whether parameters are positional or named. Mixing is not allowed. if (is_int(key($params))) { diff --git a/src/Driver/IBMDB2/Statement.php b/src/Driver/IBMDB2/Statement.php index 5047f1ee819..5642ec98e37 100644 --- a/src/Driver/IBMDB2/Statement.php +++ b/src/Driver/IBMDB2/Statement.php @@ -9,6 +9,7 @@ use Doctrine\DBAL\Driver\Result as ResultInterface; use Doctrine\DBAL\Driver\Statement as StatementInterface; use Doctrine\DBAL\ParameterType; +use Doctrine\Deprecations\Deprecation; use function assert; use function db2_bind_param; @@ -107,6 +108,15 @@ private function bind($position, &$variable, int $parameterType, int $dataType): */ public function execute($params = null): ResultInterface { + if ($params !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::execute() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.' + ); + } + $handles = $this->bindLobs(); $result = @db2_execute($this->stmt, $params ?? $this->parameters); diff --git a/src/Driver/Mysqli/Statement.php b/src/Driver/Mysqli/Statement.php index fd43f41b800..d619a7164d9 100644 --- a/src/Driver/Mysqli/Statement.php +++ b/src/Driver/Mysqli/Statement.php @@ -10,6 +10,7 @@ use Doctrine\DBAL\Driver\Result as ResultInterface; use Doctrine\DBAL\Driver\Statement as StatementInterface; use Doctrine\DBAL\ParameterType; +use Doctrine\Deprecations\Deprecation; use mysqli_sql_exception; use mysqli_stmt; @@ -102,6 +103,15 @@ public function bindValue($param, $value, $type = ParameterType::STRING): bool */ public function execute($params = null): ResultInterface { + if ($params !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::execute() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.' + ); + } + if ($params !== null && count($params) > 0) { if (! $this->bindUntypedValues($params)) { throw StatementError::new($this->stmt); diff --git a/src/Driver/OCI8/Statement.php b/src/Driver/OCI8/Statement.php index 076bc9ff791..9d65234119e 100644 --- a/src/Driver/OCI8/Statement.php +++ b/src/Driver/OCI8/Statement.php @@ -7,6 +7,7 @@ use Doctrine\DBAL\Driver\Result as ResultInterface; use Doctrine\DBAL\Driver\Statement as StatementInterface; use Doctrine\DBAL\ParameterType; +use Doctrine\Deprecations\Deprecation; use function is_int; use function oci_bind_by_name; @@ -113,6 +114,13 @@ private function convertParameterType(int $type): int public function execute($params = null): ResultInterface { if ($params !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::execute() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.' + ); + foreach ($params as $key => $val) { if (is_int($key)) { $this->bindValue($key + 1, $val); diff --git a/src/Driver/PDO/SQLSrv/Connection.php b/src/Driver/PDO/SQLSrv/Connection.php index 0e3497e633b..cc9b571e932 100644 --- a/src/Driver/PDO/SQLSrv/Connection.php +++ b/src/Driver/PDO/SQLSrv/Connection.php @@ -41,8 +41,12 @@ public function lastInsertId($name = null) 'The usage of Connection::lastInsertId() with a sequence name is deprecated.' ); - return $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?') - ->execute([$name]) + $statement = $this->prepare( + 'SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?' + ); + $statement->bindValue(1, $name); + + return $statement->execute() ->fetchOne(); } diff --git a/src/Driver/PDO/Statement.php b/src/Driver/PDO/Statement.php index 9c61bd74ec4..aae7c68408e 100644 --- a/src/Driver/PDO/Statement.php +++ b/src/Driver/PDO/Statement.php @@ -96,6 +96,15 @@ public function bindParam( */ public function execute($params = null): ResultInterface { + if ($params !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::execute() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.' + ); + } + try { $this->stmt->execute($params); } catch (PDOException $exception) { diff --git a/src/Driver/SQLSrv/Statement.php b/src/Driver/SQLSrv/Statement.php index 5255c7b9471..09c34e920a6 100644 --- a/src/Driver/SQLSrv/Statement.php +++ b/src/Driver/SQLSrv/Statement.php @@ -7,6 +7,7 @@ use Doctrine\DBAL\Driver\SQLSrv\Exception\Error; use Doctrine\DBAL\Driver\Statement as StatementInterface; use Doctrine\DBAL\ParameterType; +use Doctrine\Deprecations\Deprecation; use function assert; use function is_int; @@ -114,6 +115,13 @@ public function bindParam($param, &$variable, $type = ParameterType::STRING, $le public function execute($params = null): ResultInterface { if ($params !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::execute() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.' + ); + foreach ($params as $key => $val) { if (is_int($key)) { $this->bindValue($key + 1, $val); diff --git a/src/Statement.php b/src/Statement.php index 782feee260e..39a33f33e10 100644 --- a/src/Statement.php +++ b/src/Statement.php @@ -198,6 +198,15 @@ public function execute($params = null): Result */ public function executeQuery(array $params = []): Result { + if (func_num_args() > 0) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::executeQuery() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.' + ); + } + if ($params === []) { $params = null; // Workaround as long execute() exists and used internally. } @@ -214,6 +223,15 @@ public function executeQuery(array $params = []): Result */ public function executeStatement(array $params = []): int { + if (func_num_args() > 0) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::executeStatement() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.' + ); + } + if ($params === []) { $params = null; // Workaround as long execute() exists and used internally. } diff --git a/tests/Functional/ExceptionTest.php b/tests/Functional/ExceptionTest.php index 52e0bc09651..4cc911f1a32 100644 --- a/tests/Functional/ExceptionTest.php +++ b/tests/Functional/ExceptionTest.php @@ -22,6 +22,8 @@ use function touch; use function unlink; +use const E_ALL; +use const E_WARNING; use const PHP_OS_FAMILY; /** @@ -202,6 +204,9 @@ public function testInvalidFieldNameException(): void $table->addColumn('id', 'integer', []); $this->dropAndCreateTable($table); + // prevent the PHPUnit error handler from handling the warning that db2_bind_param() may trigger + $this->iniSet('error_reporting', (string) (E_ALL & ~E_WARNING)); + $this->expectException(Exception\InvalidFieldNameException::class); $this->connection->insert('bad_columnname_table', ['name' => 5]); }