From f0daabc63006cc411b3726953f554461d2b36cfd Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 15 Oct 2020 19:07:24 +0200 Subject: [PATCH] PHP 8 compatibility. --- composer.json | 2 +- composer.lock | 4 +- lib/Doctrine/DBAL/Driver/PDOConnection.php | 22 +-- .../DBAL/Driver/PDOConnectionTrait.php | 62 ++++++++ lib/Doctrine/DBAL/Driver/PDOStatement.php | 65 +-------- .../DBAL/Driver/PDOStatementTrait.php | 138 ++++++++++++++++++ lib/Doctrine/DBAL/Statement.php | 5 + 7 files changed, 212 insertions(+), 86 deletions(-) create mode 100644 lib/Doctrine/DBAL/Driver/PDOConnectionTrait.php create mode 100644 lib/Doctrine/DBAL/Driver/PDOStatementTrait.php diff --git a/composer.json b/composer.json index 3097561c32a..912f367f82d 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ {"name": "Jonathan Wage", "email": "jonwage@gmail.com"} ], "require": { - "php": "^7.3", + "php": "^7.3 || ^8", "ext-pdo": "*", "doctrine/cache": "^1.0", "doctrine/event-manager": "^1.0" diff --git a/composer.lock b/composer.lock index 47421ed61f9..1a59c5b34b6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "05d08a772cda388dbf5a250d750df309", + "content-hash": "214eb4a0ad0c676733b53f3d303618f5", "packages": [ { "name": "doctrine/cache", @@ -3927,7 +3927,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^7.3", + "php": "^7.3 || ^8", "ext-pdo": "*" }, "platform-dev": [], diff --git a/lib/Doctrine/DBAL/Driver/PDOConnection.php b/lib/Doctrine/DBAL/Driver/PDOConnection.php index 8409952cb4e..9b59f2fd44d 100644 --- a/lib/Doctrine/DBAL/Driver/PDOConnection.php +++ b/lib/Doctrine/DBAL/Driver/PDOConnection.php @@ -11,7 +11,6 @@ use PDOStatement; use function assert; -use function func_get_args; /** * PDO implementation of the Connection interface. @@ -21,6 +20,8 @@ */ class PDOConnection extends PDO implements ConnectionInterface, ServerInfoAwareConnection { + use PDOConnectionTrait; + /** * @internal The connection can be only instantiated by its driver. * @@ -83,25 +84,6 @@ public function prepare($sql, $driverOptions = []) } } - /** - * {@inheritdoc} - * - * @return PDOStatement - */ - public function query() - { - $args = func_get_args(); - - try { - $stmt = parent::query(...$args); - assert($stmt instanceof PDOStatement); - - return $stmt; - } catch (PDOException $exception) { - throw Exception::new($exception); - } - } - /** * {@inheritdoc} */ diff --git a/lib/Doctrine/DBAL/Driver/PDOConnectionTrait.php b/lib/Doctrine/DBAL/Driver/PDOConnectionTrait.php new file mode 100644 index 00000000000..d34986a5675 --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/PDOConnectionTrait.php @@ -0,0 +1,62 @@ += 80000) { + /** + * @internal + */ + trait PDOConnectionTrait + { + /** + * {@inheritdoc} + * + * @return PDOStatement + */ + public function query(?string $query = null, ?int $fetchMode = null, mixed ...$fetchModeArgs) + { + try { + $stmt = parent::query($query, $fetchMode, ...$fetchModeArgs); + assert($stmt instanceof PDOStatement); + + return $stmt; + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + } +} else { + /** + * @internal + */ + trait PDOConnectionTrait + { + /** + * {@inheritdoc} + * + * @return PDOStatement + */ + public function query() + { + $args = func_get_args(); + + try { + $stmt = parent::query(...$args); + assert($stmt instanceof PDOStatement); + + return $stmt; + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + } +} diff --git a/lib/Doctrine/DBAL/Driver/PDOStatement.php b/lib/Doctrine/DBAL/Driver/PDOStatement.php index 4a244ab4617..b33e11d08a9 100644 --- a/lib/Doctrine/DBAL/Driver/PDOStatement.php +++ b/lib/Doctrine/DBAL/Driver/PDOStatement.php @@ -10,9 +10,7 @@ use PDOException; use function array_slice; -use function assert; use function func_get_args; -use function is_array; use function sprintf; use function trigger_error; @@ -26,6 +24,8 @@ */ class PDOStatement extends \PDOStatement implements StatementInterface, Result { + use PDOStatementTrait; + private const PARAM_TYPE_MAP = [ ParameterType::NULL => PDO::PARAM_NULL, ParameterType::INTEGER => PDO::PARAM_INT, @@ -54,34 +54,6 @@ protected function __construct() { } - /** - * {@inheritdoc} - * - * @deprecated Use one of the fetch- or iterate-related methods. - */ - public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) - { - $fetchMode = $this->convertFetchMode($fetchMode); - - // This thin wrapper is necessary to shield against the weird signature - // of PDOStatement::setFetchMode(): even if the second and third - // parameters are optional, PHP will not let us remove it from this - // declaration. - try { - if ($arg2 === null && $arg3 === null) { - return parent::setFetchMode($fetchMode); - } - - if ($arg3 === null) { - return parent::setFetchMode($fetchMode, $arg2); - } - - return parent::setFetchMode($fetchMode, $arg2, $arg3); - } catch (PDOException $exception) { - throw Exception::new($exception); - } - } - /** * {@inheritdoc} */ @@ -164,39 +136,6 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX } } - /** - * {@inheritdoc} - * - * @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead. - */ - public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) - { - $args = func_get_args(); - - if (isset($args[0])) { - $args[0] = $this->convertFetchMode($args[0]); - } - - if ($fetchMode === null && $fetchArgument === null && $ctorArgs === null) { - $args = []; - } elseif ($fetchArgument === null && $ctorArgs === null) { - $args = [$fetchMode]; - } elseif ($ctorArgs === null) { - $args = [$fetchMode, $fetchArgument]; - } else { - $args = [$fetchMode, $fetchArgument, $ctorArgs]; - } - - try { - $data = parent::fetchAll(...$args); - assert(is_array($data)); - - return $data; - } catch (PDOException $exception) { - throw Exception::new($exception); - } - } - /** * {@inheritdoc} * diff --git a/lib/Doctrine/DBAL/Driver/PDOStatementTrait.php b/lib/Doctrine/DBAL/Driver/PDOStatementTrait.php new file mode 100644 index 00000000000..c1671e2bd77 --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/PDOStatementTrait.php @@ -0,0 +1,138 @@ += 80000) { + /** + * @internal + */ + trait PDOStatementTrait + { + /** + * {@inheritdoc} + * + * @deprecated Use one of the fetch- or iterate-related methods. + */ + public function setFetchMode($mode, ...$args) + { + $mode = $this->convertFetchMode($mode); + + $filteredArgs = array_filter($args, static function (mixed $value): bool { + return $value !== null; + }); + if (empty($filteredArgs)) { + $args = []; + } + + try { + return parent::setFetchMode($mode, ...$args); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * {@inheritdoc} + * + * @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead. + */ + public function fetchAll($mode = null, ...$args) + { + if (null !== $mode) { + $mode = $this->convertFetchMode($mode); + } + + $filteredArgs = array_filter($args, static function (mixed $value): bool { + return $value !== null; + }); + if (empty($filteredArgs)) { + $args = []; + } + + try { + $data = parent::fetchAll($mode, ...$args); + assert(is_array($data)); + + return $data; + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + } +} else { + /** + * @internal + */ + trait PDOStatementTrait + { + /** + * {@inheritdoc} + * + * @deprecated Use one of the fetch- or iterate-related methods. + */ + public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) + { + $fetchMode = $this->convertFetchMode($fetchMode); + + // This thin wrapper is necessary to shield against the weird signature + // of PDOStatement::setFetchMode(): even if the second and third + // parameters are optional, PHP will not let us remove it from this + // declaration. + try { + if ($arg2 === null && $arg3 === null) { + return parent::setFetchMode($fetchMode); + } + + if ($arg3 === null) { + return parent::setFetchMode($fetchMode, $arg2); + } + + return parent::setFetchMode($fetchMode, $arg2, $arg3); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * {@inheritdoc} + * + * @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead. + */ + public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) + { + $args = func_get_args(); + + if (isset($args[0])) { + $args[0] = $this->convertFetchMode($args[0]); + } + + if ($fetchMode === null && $fetchArgument === null && $ctorArgs === null) { + $args = []; + } elseif ($fetchArgument === null && $ctorArgs === null) { + $args = [$fetchMode]; + } elseif ($ctorArgs === null) { + $args = [$fetchMode, $fetchArgument]; + } else { + $args = [$fetchMode, $fetchArgument, $ctorArgs]; + } + + try { + $data = parent::fetchAll(...$args); + assert(is_array($data)); + + return $data; + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + } +} diff --git a/lib/Doctrine/DBAL/Statement.php b/lib/Doctrine/DBAL/Statement.php index ad5d29b9a5d..57843031eea 100644 --- a/lib/Doctrine/DBAL/Statement.php +++ b/lib/Doctrine/DBAL/Statement.php @@ -10,6 +10,7 @@ use Doctrine\DBAL\Types\Type; use IteratorAggregate; use PDO; +use PDOStatement; use Throwable; use Traversable; @@ -135,6 +136,10 @@ public function bindParam($param, &$variable, $type = ParameterType::STRING, $le $this->params[$param] = $variable; $this->types[$param] = $type; + if ($this->stmt instanceof PDOStatement) { + $length = $length ?? 0; + } + return $this->stmt->bindParam($param, $variable, $type, $length); }