diff --git a/UPGRADE.md b/UPGRADE.md
index f70392c0a0d..b5333f01e85 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -14,9 +14,10 @@ The following classes have been converted to enums:
1. `Doctrine\DBAL\ColumnCase`,
2. `Doctrine\DBAL\LockMode`,
-3. `Doctrine\DBAL\TransactionIsolationLevel`,
-4. `Doctrine\DBAL\Platforms\DateIntervalUnit`,
-5. `Doctrine\DBAL\Platforms\TrimMode`.
+3. `Doctrine\DBAL\ParameterType`,
+4. `Doctrine\DBAL\TransactionIsolationLevel`,
+5. `Doctrine\DBAL\Platforms\DateIntervalUnit`,
+6. `Doctrine\DBAL\Platforms\TrimMode`.
The corresponding class constants are now instances of their enum type.
diff --git a/docs/en/reference/data-retrieval-and-manipulation.rst b/docs/en/reference/data-retrieval-and-manipulation.rst
index 23fae97a01d..cfa04e83a07 100644
--- a/docs/en/reference/data-retrieval-and-manipulation.rst
+++ b/docs/en/reference/data-retrieval-and-manipulation.rst
@@ -187,13 +187,13 @@ on the Connection, which are all described in the API section below.
Binding Types
-------------
-Besides ``Doctrine\DBAL\ParameterType`` constants, you
+Besides the values of ``Doctrine\DBAL\ParameterType``, you
can make use of two very powerful additional features.
Doctrine\DBAL\Types Conversion
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If you don't specify an integer (through one of ``Doctrine\DBAL\ParameterType`` constants) to
+If you don't specify a value of the type ``Doctrine\DBAL\ParameterType`` to
any of the parameter binding methods but a string, Doctrine DBAL will
ask the type abstraction layer to convert the passed value from
its PHP to a database representation. This way you can pass ``\DateTime``
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index 93510b9d2c0..951ab36a0e3 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -119,4 +119,14 @@
src/Platforms/SQLitePlatform.php
src/Platforms/*/Comparator.php
+
+
+
+ src/ParameterType.php
+
+
+
+
+ src/Cache/QueryCacheProfile.php
+
diff --git a/src/Driver/Exception/UnknownParameterType.php b/src/ArrayParameters/Exception/InvalidParameterType.php
similarity index 56%
rename from src/Driver/Exception/UnknownParameterType.php
rename to src/ArrayParameters/Exception/InvalidParameterType.php
index 49cf6c9d702..c1041c76fd8 100644
--- a/src/Driver/Exception/UnknownParameterType.php
+++ b/src/ArrayParameters/Exception/InvalidParameterType.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Doctrine\DBAL\Driver\Exception;
+namespace Doctrine\DBAL\ArrayParameters\Exception;
use Doctrine\DBAL\Driver\AbstractException;
@@ -13,10 +13,10 @@
*
* @psalm-immutable
*/
-final class UnknownParameterType extends AbstractException
+final class InvalidParameterType extends AbstractException
{
public static function new(int $type): self
{
- return new self(sprintf('Unknown parameter type, %d given.', $type));
+ return new self(sprintf('Invalid parameter type, %d given.', $type));
}
}
diff --git a/src/Cache/QueryCacheProfile.php b/src/Cache/QueryCacheProfile.php
index a18d6e9e1bb..4633dc01396 100644
--- a/src/Cache/QueryCacheProfile.php
+++ b/src/Cache/QueryCacheProfile.php
@@ -5,6 +5,7 @@
namespace Doctrine\DBAL\Cache;
use Doctrine\DBAL\Cache\Exception\NoCacheKey;
+use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Types\Type;
use Psr\Cache\CacheItemPoolInterface;
@@ -51,9 +52,9 @@ public function getCacheKey(): string
/**
* Generates the real cache key from query, params, types and connection parameters.
*
- * @param list|array $params
- * @param array|array $types
- * @param array $connectionParams
+ * @param list|array $params
+ * @param array|array $types
+ * @param array $connectionParams
*
* @return string[]
*/
diff --git a/src/Connection.php b/src/Connection.php
index 7c313068ae6..a993755fa96 100644
--- a/src/Connection.php
+++ b/src/Connection.php
@@ -54,26 +54,19 @@
class Connection implements ServerVersionProvider
{
/**
- * Represents an array of ints to be expanded by Doctrine SQL parsing.
+ * Represents an array of integers to be expanded by Doctrine SQL parsing.
*/
- final public const PARAM_INT_ARRAY = ParameterType::INTEGER + self::ARRAY_PARAM_OFFSET;
+ final public const PARAM_INT_ARRAY = 101;
/**
* Represents an array of strings to be expanded by Doctrine SQL parsing.
*/
- final public const PARAM_STR_ARRAY = ParameterType::STRING + self::ARRAY_PARAM_OFFSET;
+ final public const PARAM_STR_ARRAY = 102;
/**
* Represents an array of ascii strings to be expanded by Doctrine SQL parsing.
*/
- final public const PARAM_ASCII_STR_ARRAY = ParameterType::ASCII + self::ARRAY_PARAM_OFFSET;
-
- /**
- * Offset by which PARAM_* constants are detected as arrays of the param type.
- *
- * @internal Should be used only within the wrapper layer.
- */
- final public const ARRAY_PARAM_OFFSET = 100;
+ final public const PARAM_ASCII_STR_ARRAY = 117;
/**
* The wrapped driver connection.
@@ -368,8 +361,8 @@ public function setAutoCommit(bool $autoCommit): void
* Prepares and executes an SQL query and returns the first row of the result
* as an associative array.
*
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @return array|false False is returned if no rows are found.
*
@@ -384,8 +377,8 @@ public function fetchAssociative(string $query, array $params = [], array $types
* Prepares and executes an SQL query and returns the first row of the result
* as a numerically indexed array.
*
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @return list|false False is returned if no rows are found.
*
@@ -400,8 +393,8 @@ public function fetchNumeric(string $query, array $params = [], array $types = [
* Prepares and executes an SQL query and returns the value of a single column
* of the first row of the result.
*
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @return mixed|false False is returned if no rows are found.
*
@@ -463,8 +456,8 @@ private function addCriteriaCondition(
*
* Table expression and columns are not escaped and are not safe for user-input.
*
- * @param array $criteria Deletion criteria
- * @param array|array $types Parameter types
+ * @param array $criteria
+ * @param array|array $types
*
* @return int|string The number of affected rows.
*
@@ -527,9 +520,9 @@ public function getTransactionIsolation(): TransactionIsolationLevel
*
* Table expression and columns are not escaped and are not safe for user-input.
*
- * @param array $data Column-value pairs
- * @param array $criteria Update criteria
- * @param array|array $types Parameter types
+ * @param array $data
+ * @param array $criteria
+ * @param array|array $types
*
* @return int|string The number of affected rows.
*
@@ -562,8 +555,8 @@ public function update(string $table, array $data, array $criteria, array $types
*
* Table expression and columns are not escaped and are not safe for user-input.
*
- * @param array $data Column-value pairs
- * @param array|array $types Parameter types
+ * @param array $data
+ * @param array|array $types
*
* @return int|string The number of affected rows.
*
@@ -596,16 +589,16 @@ public function insert(string $table, array $data, array $types = []): int|strin
/**
* Extract ordered type list from an ordered column list and type map.
*
- * @param array $columnList
- * @param array|array $types
+ * @param array $columns
+ * @param array|array $types
*
- * @return array|array
+ * @return array|array
*/
- private function extractTypeValues(array $columnList, array $types): array
+ private function extractTypeValues(array $columns, array $types): array
{
$typeValues = [];
- foreach ($columnList as $columnName) {
+ foreach ($columns as $columnName) {
$typeValues[] = $types[$columnName] ?? ParameterType::STRING;
}
@@ -643,8 +636,8 @@ public function quote(string $value): string
/**
* Prepares and executes an SQL query and returns the result as an array of numeric arrays.
*
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @return list>
*
@@ -658,8 +651,8 @@ public function fetchAllNumeric(string $query, array $params = [], array $types
/**
* Prepares and executes an SQL query and returns the result as an array of associative arrays.
*
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @return list>
*
@@ -674,8 +667,8 @@ public function fetchAllAssociative(string $query, array $params = [], array $ty
* Prepares and executes an SQL query and returns the result as an associative array with the keys
* mapped to the first column and the values mapped to the second column.
*
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @return array
*
@@ -691,9 +684,8 @@ public function fetchAllKeyValue(string $query, array $params = [], array $types
* to the first column and the values being an associative array representing the rest of the columns
* and their values.
*
- * @param string $query SQL query
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @return array>
*
@@ -707,8 +699,8 @@ public function fetchAllAssociativeIndexed(string $query, array $params = [], ar
/**
* Prepares and executes an SQL query and returns the result as an array of the first column values.
*
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @return list
*
@@ -722,8 +714,8 @@ public function fetchFirstColumn(string $query, array $params = [], array $types
/**
* Prepares and executes an SQL query and returns the result as an iterator over rows represented as numeric arrays.
*
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @return Traversable>
*
@@ -738,8 +730,8 @@ public function iterateNumeric(string $query, array $params = [], array $types =
* Prepares and executes an SQL query and returns the result as an iterator over rows represented
* as associative arrays.
*
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @return Traversable>
*
@@ -754,8 +746,8 @@ public function iterateAssociative(string $query, array $params = [], array $typ
* Prepares and executes an SQL query and returns the result as an iterator with the keys
* mapped to the first column and the values mapped to the second column.
*
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @return Traversable
*
@@ -771,9 +763,9 @@ public function iterateKeyValue(string $query, array $params = [], array $types
* to the first column and the values being an associative array representing the rest of the columns
* and their values.
*
- * @param string $query SQL query
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param string $query SQL query
+ * @param list|array $params
+ * @param array|array $types
*
* @return Traversable>
*
@@ -787,8 +779,8 @@ public function iterateAssociativeIndexed(string $query, array $params = [], arr
/**
* Prepares and executes an SQL query and returns the result as an iterator over the first column values.
*
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @return Traversable
*
@@ -824,8 +816,8 @@ public function prepare(string $sql): Statement
*
* If the query is parametrized, a prepared statement is used.
*
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @throws Exception
*/
@@ -843,9 +835,7 @@ public function executeQuery(
try {
if (count($params) > 0) {
- if ($this->needsArrayParameterConversion($params, $types)) {
- [$sql, $params, $types] = $this->expandArrayParameters($sql, $params, $types);
- }
+ [$sql, $params, $types] = $this->expandArrayParameters($sql, $params, $types);
$stmt = $connection->prepare($sql);
if (count($types) > 0) {
@@ -867,8 +857,8 @@ public function executeQuery(
/**
* Executes a caching query.
*
- * @param list|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @throws CacheException
* @throws Exception
@@ -925,8 +915,8 @@ public function executeCacheQuery(string $sql, array $params, array $types, Quer
*
* This method supports PDO binding types as well as DBAL mapping types.
*
- * @param list|array $params Statement parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @throws Exception
*/
@@ -936,9 +926,7 @@ public function executeStatement(string $sql, array $params = [], array $types =
try {
if (count($params) > 0) {
- if ($this->needsArrayParameterConversion($params, $types)) {
- [$sql, $params, $types] = $this->expandArrayParameters($sql, $params, $types);
- }
+ [$sql, $params, $types] = $this->expandArrayParameters($sql, $params, $types);
$stmt = $connection->prepare($sql);
@@ -1321,9 +1309,8 @@ public function convertToPHPValue(mixed $value, string $type): mixed
* Binds a set of parameters, some or all of which are typed with a PDO binding type
* or DBAL mapping type, to a given statement.
*
- * @param DriverStatement $stmt Prepared statement
- * @param list|array $params Statement parameters
- * @param array|array $types Parameter types
+ * @param list|array $params
+ * @param array|array $types
*
* @throws Exception
*/
@@ -1379,14 +1366,14 @@ private function _bindTypedValues(DriverStatement $stmt, array $params, array $t
/**
* Gets the binding type of a given type.
*
- * @param mixed $value The value to bind.
- * @param int|string|Type|null $type The type to bind (PDO or DBAL).
+ * @param mixed $value The value to bind.
+ * @param string|ParameterType|Type|null $type The type to bind.
*
- * @return array{mixed, int} [0] => the (escaped) value, [1] => the binding type.
+ * @return array{mixed, ParameterType} [0] => the (escaped) value, [1] => the binding type.
*
* @throws Exception
*/
- private function getBindingInfo(mixed $value, int|string|Type|null $type): array
+ private function getBindingInfo(mixed $value, string|ParameterType|Type|null $type): array
{
if (is_string($type)) {
$type = Type::getType($type);
@@ -1413,8 +1400,8 @@ public function createQueryBuilder(): QueryBuilder
/**
* @internal
*
- * @param list|array $params
- * @param array|array $types
+ * @param list|array $params
+ * @param array|array $types
*/
final public function convertExceptionDuringQuery(
Driver\Exception $e,
@@ -1434,13 +1421,37 @@ final public function convertException(Driver\Exception $e): DriverException
}
/**
- * @param array|array $params
- * @param array|array $types
+ * @param array|array $params
+ * @param array|array $types
*
- * @return array{string, list, array}
+ * @return array{
+ * string,
+ * array|array,
+ * array|array
+ * }
*/
private function expandArrayParameters(string $sql, array $params, array $types): array
{
+ $needsConversion = false;
+ $nonArrayTypes = [];
+
+ if (is_string(key($params))) {
+ $needsConversion = true;
+ } else {
+ foreach ($types as $key => $type) {
+ if (is_int($type)) {
+ $needsConversion = true;
+ break;
+ }
+
+ $nonArrayTypes[$key] = $type;
+ }
+ }
+
+ if (! $needsConversion) {
+ return [$sql, $params, $nonArrayTypes];
+ }
+
$this->parser ??= $this->getDatabasePlatform()->createSQLParser();
$visitor = new ExpandArrayParameters($params, $types);
@@ -1453,29 +1464,6 @@ private function expandArrayParameters(string $sql, array $params, array $types)
];
}
- /**
- * @param array|array $params
- * @param array|array $types
- */
- private function needsArrayParameterConversion(array $params, array $types): bool
- {
- if (is_string(key($params))) {
- return true;
- }
-
- foreach ($types as $type) {
- if (
- $type === self::PARAM_INT_ARRAY
- || $type === self::PARAM_STR_ARRAY
- || $type === self::PARAM_ASCII_STR_ARRAY
- ) {
- return true;
- }
- }
-
- return false;
- }
-
private function handleDriverException(
Driver\Exception $driverException,
?Query $query
@@ -1495,8 +1483,8 @@ private function handleDriverException(
*
* @deprecated This API is deprecated and will be removed after 2022
*
- * @param array|array $params Query parameters
- * @param array|array $types Parameter types
+ * @param array|array $params
+ * @param array|array $types
*
* @throws Exception
*/
diff --git a/src/Driver/IBMDB2/Statement.php b/src/Driver/IBMDB2/Statement.php
index ac8e636595c..9b46e7599f1 100644
--- a/src/Driver/IBMDB2/Statement.php
+++ b/src/Driver/IBMDB2/Statement.php
@@ -50,7 +50,7 @@ public function __construct(private readonly mixed $stmt)
{
}
- public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
+ public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
assert(is_int($param));
@@ -60,7 +60,7 @@ public function bindValue(int|string $param, mixed $value, int $type = Parameter
public function bindParam(
int|string $param,
mixed &$variable,
- int $type = ParameterType::STRING,
+ ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
assert(is_int($param));
diff --git a/src/Driver/Middleware/AbstractStatementMiddleware.php b/src/Driver/Middleware/AbstractStatementMiddleware.php
index ef3c6db8d8c..152fb52f482 100644
--- a/src/Driver/Middleware/AbstractStatementMiddleware.php
+++ b/src/Driver/Middleware/AbstractStatementMiddleware.php
@@ -14,7 +14,7 @@ public function __construct(private readonly Statement $wrappedStatement)
{
}
- public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
+ public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
$this->wrappedStatement->bindValue($param, $value, $type);
}
@@ -22,7 +22,7 @@ public function bindValue(int|string $param, mixed $value, int $type = Parameter
public function bindParam(
int|string $param,
mixed &$variable,
- int $type = ParameterType::STRING,
+ ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
$this->wrappedStatement->bindParam($param, $variable, $type, $length);
diff --git a/src/Driver/Mysqli/Statement.php b/src/Driver/Mysqli/Statement.php
index 961d5b35503..2d555715a71 100644
--- a/src/Driver/Mysqli/Statement.php
+++ b/src/Driver/Mysqli/Statement.php
@@ -5,7 +5,6 @@
namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\Exception;
-use Doctrine\DBAL\Driver\Exception\UnknownParameterType;
use Doctrine\DBAL\Driver\Mysqli\Exception\FailedReadingStreamOffset;
use Doctrine\DBAL\Driver\Mysqli\Exception\NonStreamResourceUsedAsLargeObject;
use Doctrine\DBAL\Driver\Mysqli\Exception\StatementError;
@@ -26,16 +25,9 @@
final class Statement implements StatementInterface
{
- /** @var string[] */
- private static array $paramTypeMap = [
- ParameterType::ASCII => 's',
- ParameterType::STRING => 's',
- ParameterType::BINARY => 's',
- ParameterType::BOOLEAN => 'i',
- ParameterType::NULL => 's',
- ParameterType::INTEGER => 'i',
- ParameterType::LARGE_OBJECT => 'b',
- ];
+ private const PARAMETER_TYPE_STRING = 's';
+ private const PARAMETER_TYPE_INTEGER = 'i';
+ private const PARAMETER_TYPE_BINARY = 'b';
/** @var mixed[] */
private array $boundValues;
@@ -55,37 +47,29 @@ final class Statement implements StatementInterface
public function __construct(private readonly mysqli_stmt $stmt)
{
$paramCount = $this->stmt->param_count;
- $this->types = str_repeat('s', $paramCount);
+ $this->types = str_repeat(self::PARAMETER_TYPE_STRING, $paramCount);
$this->boundValues = array_fill(1, $paramCount, null);
}
public function bindParam(
int|string $param,
mixed &$variable,
- int $type = ParameterType::STRING,
+ ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
assert(is_int($param));
- if (! isset(self::$paramTypeMap[$type])) {
- throw UnknownParameterType::new($type);
- }
-
+ $this->types[$param - 1] = $this->convertParameterType($type);
$this->boundValues[$param] =& $variable;
- $this->types[$param - 1] = self::$paramTypeMap[$type];
}
- public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
+ public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
assert(is_int($param));
- if (! isset(self::$paramTypeMap[$type])) {
- throw UnknownParameterType::new($type);
- }
-
+ $this->types[$param - 1] = $this->convertParameterType($type);
$this->values[$param] = $value;
$this->boundValues[$param] =& $this->values[$param];
- $this->types[$param - 1] = self::$paramTypeMap[$type];
}
public function execute(?array $params = null): Result
@@ -120,10 +104,10 @@ private function bindTypedParameters(): void
foreach ($this->boundValues as $parameter => $value) {
assert(is_int($parameter));
if (! isset($types[$parameter - 1])) {
- $types[$parameter - 1] = self::$paramTypeMap[ParameterType::STRING];
+ $types[$parameter - 1] = self::PARAMETER_TYPE_STRING;
}
- if ($types[$parameter - 1] === self::$paramTypeMap[ParameterType::LARGE_OBJECT]) {
+ if ($types[$parameter - 1] === self::PARAMETER_TYPE_BINARY) {
if (is_resource($value)) {
if (get_resource_type($value) !== 'stream') {
throw NonStreamResourceUsedAsLargeObject::new($parameter);
@@ -134,7 +118,7 @@ private function bindTypedParameters(): void
continue;
}
- $types[$parameter - 1] = self::$paramTypeMap[ParameterType::STRING];
+ $types[$parameter - 1] = self::PARAMETER_TYPE_STRING;
}
$values[$parameter] = $value;
@@ -180,8 +164,21 @@ private function sendLongData(array $streams): void
*/
private function bindUntypedValues(array $values): void
{
- if (! $this->stmt->bind_param(str_repeat('s', count($values)), ...$values)) {
+ if (! $this->stmt->bind_param(str_repeat(self::PARAMETER_TYPE_STRING, count($values)), ...$values)) {
throw StatementError::new($this->stmt);
}
}
+
+ private function convertParameterType(ParameterType $type): string
+ {
+ return match ($type) {
+ ParameterType::NULL,
+ ParameterType::STRING,
+ ParameterType::ASCII,
+ ParameterType::BINARY => self::PARAMETER_TYPE_STRING,
+ ParameterType::INTEGER,
+ ParameterType::BOOLEAN => self::PARAMETER_TYPE_INTEGER,
+ ParameterType::LARGE_OBJECT => self::PARAMETER_TYPE_BINARY,
+ };
+ }
}
diff --git a/src/Driver/OCI8/Statement.php b/src/Driver/OCI8/Statement.php
index fb643d495bf..c3ab57e6e4d 100644
--- a/src/Driver/OCI8/Statement.php
+++ b/src/Driver/OCI8/Statement.php
@@ -39,7 +39,7 @@ public function __construct(
) {
}
- public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
+ public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
$this->bindParam($param, $value, $type);
}
@@ -47,7 +47,7 @@ public function bindValue(int|string $param, mixed $value, int $type = Parameter
public function bindParam(
int|string $param,
mixed &$variable,
- int $type = ParameterType::STRING,
+ ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
if (is_int($param)) {
@@ -85,7 +85,7 @@ public function bindParam(
/**
* Converts DBAL parameter type to oci8 parameter type
*/
- private function convertParameterType(int $type): int
+ private function convertParameterType(ParameterType $type): int
{
return match ($type) {
ParameterType::BINARY => OCI_B_BIN,
diff --git a/src/Driver/PDO/SQLSrv/Statement.php b/src/Driver/PDO/SQLSrv/Statement.php
index de1e66c3343..0461d928d30 100644
--- a/src/Driver/PDO/SQLSrv/Statement.php
+++ b/src/Driver/PDO/SQLSrv/Statement.php
@@ -26,7 +26,7 @@ public function __construct(PDOStatement $statement)
public function bindParam(
int|string $param,
mixed &$variable,
- int $type = ParameterType::STRING,
+ ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
switch ($type) {
@@ -56,7 +56,7 @@ public function bindParam(
}
}
- public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
+ public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
$this->bindParam($param, $value, $type);
}
diff --git a/src/Driver/PDO/Statement.php b/src/Driver/PDO/Statement.php
index 56984acb7d2..fa1f5a75970 100644
--- a/src/Driver/PDO/Statement.php
+++ b/src/Driver/PDO/Statement.php
@@ -5,7 +5,6 @@
namespace Doctrine\DBAL\Driver\PDO;
use Doctrine\DBAL\Driver\Exception as ExceptionInterface;
-use Doctrine\DBAL\Driver\Exception\UnknownParameterType;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType;
use PDO;
@@ -14,16 +13,6 @@
final class Statement implements StatementInterface
{
- private const PARAM_TYPE_MAP = [
- ParameterType::NULL => PDO::PARAM_NULL,
- ParameterType::INTEGER => PDO::PARAM_INT,
- ParameterType::STRING => PDO::PARAM_STR,
- ParameterType::ASCII => PDO::PARAM_STR,
- ParameterType::BINARY => PDO::PARAM_LOB,
- ParameterType::LARGE_OBJECT => PDO::PARAM_LOB,
- ParameterType::BOOLEAN => PDO::PARAM_BOOL,
- ];
-
/**
* @internal The statement can be only instantiated by its driver connection.
*/
@@ -31,7 +20,7 @@ public function __construct(private readonly PDOStatement $stmt)
{
}
- public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
+ public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
$type = $this->convertParamType($type);
@@ -45,7 +34,7 @@ public function bindValue(int|string $param, mixed $value, int $type = Parameter
public function bindParam(
string|int $param,
mixed &$variable,
- int $type = ParameterType::STRING,
+ ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
try {
@@ -67,7 +56,7 @@ public function bindParam(
public function bindParamWithDriverOptions(
string|int $param,
mixed &$variable,
- int $type,
+ ParameterType $type,
int $length,
mixed $driverOptions
): void {
@@ -91,17 +80,17 @@ public function execute(?array $params = null): Result
/**
* Converts DBAL parameter type to PDO parameter type
- *
- * @param int $type Parameter type
- *
- * @throws ExceptionInterface
*/
- private function convertParamType(int $type): int
+ private function convertParamType(ParameterType $type): int
{
- if (! isset(self::PARAM_TYPE_MAP[$type])) {
- throw UnknownParameterType::new($type);
- }
-
- return self::PARAM_TYPE_MAP[$type];
+ return match ($type) {
+ ParameterType::NULL => PDO::PARAM_NULL,
+ ParameterType::INTEGER => PDO::PARAM_INT,
+ ParameterType::STRING,
+ ParameterType::ASCII => PDO::PARAM_STR,
+ ParameterType::BINARY,
+ ParameterType::LARGE_OBJECT => PDO::PARAM_LOB,
+ ParameterType::BOOLEAN => PDO::PARAM_BOOL,
+ };
}
}
diff --git a/src/Driver/SQLSrv/Statement.php b/src/Driver/SQLSrv/Statement.php
index b14bbe0ec5f..eb860dfcebd 100644
--- a/src/Driver/SQLSrv/Statement.php
+++ b/src/Driver/SQLSrv/Statement.php
@@ -41,7 +41,7 @@ final class Statement implements StatementInterface
/**
* Bound parameter types.
*
- * @var array
+ * @var array
*/
private array $types = [];
@@ -66,7 +66,7 @@ public function __construct(
$this->sql .= self::LAST_INSERT_ID_SQL;
}
- public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
+ public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
assert(is_int($param));
@@ -77,7 +77,7 @@ public function bindValue(int|string $param, mixed $value, int $type = Parameter
public function bindParam(
int|string $param,
mixed &$variable,
- int $type = ParameterType::STRING,
+ ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
assert(is_int($param));
diff --git a/src/Driver/Statement.php b/src/Driver/Statement.php
index 2a4bc6ab812..9ded2932196 100644
--- a/src/Driver/Statement.php
+++ b/src/Driver/Statement.php
@@ -18,16 +18,17 @@ interface Statement
* As mentioned above, the named parameters are not natively supported by the mysqli driver, use executeQuery(),
* fetchAll(), fetchArray(), fetchColumn(), fetchAssoc() methods to have the named parameter emulated by doctrine.
*
- * @param int|string $param Parameter identifier. For a prepared statement using named placeholders,
- * this will be a parameter name of the form :name. For a prepared statement
- * using question mark placeholders, this will be the 1-indexed position of the parameter.
- * @param mixed $value The value to bind to the parameter.
- * @param int $type Explicit data type for the parameter using the {@see ParameterType}
- * constants.
+ * @param int|string $param Parameter identifier. For a prepared statement using named placeholders,
+ * this will be a parameter name of the form :name. For a prepared statement
+ * using question mark placeholders, this will be the 1-indexed position
+ * of the parameter.
+ * @param mixed $value The value to bind to the parameter.
+ * @param ParameterType $type Explicit data type for the parameter using the {@see ParameterType}
+ * constants.
*
* @throws Exception
*/
- public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void;
+ public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void;
/**
* Binds a PHP variable to a corresponding named (not supported by mysqli driver, see comment below) or question
@@ -43,21 +44,21 @@ public function bindValue(int|string $param, mixed $value, int $type = Parameter
* of stored procedures that return data as output parameters, and some also as input/output
* parameters that both send in data and are updated to receive it.
*
- * @param int|string $param Parameter identifier. For a prepared statement using named placeholders,
- * this will be a parameter name of the form :name. For a prepared statement using
- * question mark placeholders, this will be the 1-indexed position of the parameter.
- * @param mixed $variable The variable to bind to the parameter.
- * @param int $type Explicit data type for the parameter using the {@see ParameterType}
+ * @param int|string $param Parameter identifier. For a prepared statement using named placeholders,
+ * this will be a parameter name of the form :name. For a prepared statement using
+ * question mark placeholders, this will be the 1-indexed position of the parameter.
+ * @param mixed $variable The variable to bind to the parameter.
+ * @param ParameterType $type Explicit data type for the parameter using the {@see ParameterType}
* constants.
- * @param int|null $length You must specify maxlength when using an OUT bind
- * so that PHP allocates enough memory to hold the returned value.
+ * @param int|null $length You must specify maxlength when using an OUT bind
+ * so that PHP allocates enough memory to hold the returned value.
*
* @throws Exception
*/
public function bindParam(
int|string $param,
mixed &$variable,
- int $type = ParameterType::STRING,
+ ParameterType $type = ParameterType::STRING,
?int $length = null
): void;
diff --git a/src/ExpandArrayParameters.php b/src/ExpandArrayParameters.php
index 000096705a9..0e7e8ad2c50 100644
--- a/src/ExpandArrayParameters.php
+++ b/src/ExpandArrayParameters.php
@@ -4,6 +4,7 @@
namespace Doctrine\DBAL;
+use Doctrine\DBAL\ArrayParameters\Exception\InvalidParameterType;
use Doctrine\DBAL\ArrayParameters\Exception\MissingNamedParameter;
use Doctrine\DBAL\ArrayParameters\Exception\MissingPositionalParameter;
use Doctrine\DBAL\SQL\Parser\Visitor;
@@ -13,6 +14,7 @@
use function array_key_exists;
use function count;
use function implode;
+use function is_int;
use function substr;
final class ExpandArrayParameters implements Visitor
@@ -23,16 +25,16 @@ final class ExpandArrayParameters implements Visitor
private array $convertedSQL = [];
/** @var list */
- private array $convertedParameteres = [];
+ private array $convertedParameters = [];
- /** @var array */
+ /** @var array */
private array $convertedTypes = [];
/**
- * @param array|array $originalParameters
- * @param array|array $originalTypes
+ * @param array|array $parameters
+ * @param array|array $types
*/
- public function __construct(private readonly array $originalParameters, private readonly array $originalTypes)
+ public function __construct(private readonly array $parameters, private readonly array $types)
{
}
@@ -40,11 +42,11 @@ public function acceptPositionalParameter(string $sql): void
{
$index = $this->originalParameterIndex;
- if (! array_key_exists($index, $this->originalParameters)) {
+ if (! array_key_exists($index, $this->parameters)) {
throw MissingPositionalParameter::new($index);
}
- $this->acceptParameter($index, $this->originalParameters[$index]);
+ $this->acceptParameter($index, $this->parameters[$index]);
$this->originalParameterIndex++;
}
@@ -53,11 +55,11 @@ public function acceptNamedParameter(string $sql): void
{
$name = substr($sql, 1);
- if (! array_key_exists($name, $this->originalParameters)) {
+ if (! array_key_exists($name, $this->parameters)) {
throw MissingNamedParameter::new($name);
}
- $this->acceptParameter($name, $this->originalParameters[$name]);
+ $this->acceptParameter($name, $this->parameters[$name]);
}
public function acceptOther(string $sql): void
@@ -75,25 +77,24 @@ public function getSQL(): string
*/
public function getParameters(): array
{
- return $this->convertedParameteres;
+ return $this->convertedParameters;
}
+ /**
+ * @throws InvalidParameterType
+ */
private function acceptParameter(int|string $key, mixed $value): void
{
- if (! isset($this->originalTypes[$key])) {
- $this->convertedSQL[] = '?';
- $this->convertedParameteres[] = $value;
+ if (! isset($this->types[$key])) {
+ $this->convertedSQL[] = '?';
+ $this->convertedParameters[] = $value;
return;
}
- $type = $this->originalTypes[$key];
+ $type = $this->types[$key];
- if (
- $type !== Connection::PARAM_INT_ARRAY
- && $type !== Connection::PARAM_STR_ARRAY
- && $type !== Connection::PARAM_ASCII_STR_ARRAY
- ) {
+ if (! is_int($type)) {
$this->appendTypedParameter([$value], $type);
return;
@@ -105,11 +106,16 @@ private function acceptParameter(int|string $key, mixed $value): void
return;
}
- $this->appendTypedParameter($value, $type - Connection::ARRAY_PARAM_OFFSET);
+ $this->appendTypedParameter($value, match ($type) {
+ Connection::PARAM_INT_ARRAY => ParameterType::INTEGER,
+ Connection::PARAM_STR_ARRAY => ParameterType::STRING,
+ Connection::PARAM_ASCII_STR_ARRAY => ParameterType::ASCII,
+ default => throw InvalidParameterType::new($type),
+ });
}
/**
- * @return array
+ * @return array
*/
public function getTypes(): array
{
@@ -119,14 +125,14 @@ public function getTypes(): array
/**
* @param list $values
*/
- private function appendTypedParameter(array $values, Type|int|string|null $type): void
+ private function appendTypedParameter(array $values, string|ParameterType|Type|null $type): void
{
$this->convertedSQL[] = implode(', ', array_fill(0, count($values), '?'));
- $index = count($this->convertedParameteres);
+ $index = count($this->convertedParameters);
foreach ($values as $value) {
- $this->convertedParameteres[] = $value;
+ $this->convertedParameters[] = $value;
$this->convertedTypes[$index] = $type;
$index++;
diff --git a/src/Logging/Statement.php b/src/Logging/Statement.php
index 8e75e8ac84d..e1806b6c7ab 100644
--- a/src/Logging/Statement.php
+++ b/src/Logging/Statement.php
@@ -15,7 +15,7 @@ final class Statement extends AbstractStatementMiddleware
/** @var array|array */
private array $params = [];
- /** @var array|array */
+ /** @var array|array */
private array $types = [];
/**
@@ -32,7 +32,7 @@ public function __construct(
public function bindParam(
int|string $param,
mixed &$variable,
- int $type = ParameterType::STRING,
+ ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
$this->params[$param] = &$variable;
@@ -41,7 +41,7 @@ public function bindParam(
parent::bindParam($param, $variable, $type, $length);
}
- public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
+ public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
$this->params[$param] = $value;
$this->types[$param] = $type;
diff --git a/src/ParameterType.php b/src/ParameterType.php
index 51970b06e8d..19f577ec322 100644
--- a/src/ParameterType.php
+++ b/src/ParameterType.php
@@ -5,55 +5,42 @@
namespace Doctrine\DBAL;
/**
- * Contains statement parameter types.
+ * Statement parameter type.
*/
-final class ParameterType
+enum ParameterType
{
/**
* Represents the SQL NULL data type.
*/
- public const NULL = 0;
+ case NULL;
/**
* Represents the SQL INTEGER data type.
*/
- public const INTEGER = 1;
+ case INTEGER;
/**
* Represents the SQL CHAR, VARCHAR, or other string data type.
- *
- * @see \PDO::PARAM_STR
*/
- public const STRING = 2;
+ case STRING;
/**
* Represents the SQL large object data type.
*/
- public const LARGE_OBJECT = 3;
+ case LARGE_OBJECT;
/**
* Represents a boolean data type.
- *
- * @see \PDO::PARAM_BOOL
*/
- public const BOOLEAN = 5;
+ case BOOLEAN;
/**
* Represents a binary string data type.
*/
- public const BINARY = 16;
+ case BINARY;
/**
* Represents an ASCII string data type
*/
- public const ASCII = 17;
-
- /**
- * This class cannot be instantiated.
- *
- * @codeCoverageIgnore
- */
- private function __construct()
- {
- }
+ case ASCII;
}
diff --git a/src/Query.php b/src/Query.php
index 462cdc6aec9..82e92f3a23b 100644
--- a/src/Query.php
+++ b/src/Query.php
@@ -14,8 +14,8 @@
final class Query
{
/**
- * @param array $params
- * @param array $types
+ * @param array $params
+ * @param array $types
*
* @psalm-suppress ImpurePropertyAssignment
*/
@@ -40,7 +40,7 @@ public function getParams(): array
}
/**
- * @return array
+ * @return array
*/
public function getTypes(): array
{
diff --git a/src/Query/QueryBuilder.php b/src/Query/QueryBuilder.php
index 60d6178d9aa..6976cb08059 100644
--- a/src/Query/QueryBuilder.php
+++ b/src/Query/QueryBuilder.php
@@ -52,9 +52,9 @@ class QueryBuilder
/**
* The parameter type map of this query.
*
- * @var array|array
+ * @var array|array
*/
- private array $paramTypes = [];
+ private array $types = [];
/**
* The type of query this is. Can be select, update or delete.
@@ -191,7 +191,7 @@ public function getConnection(): Connection
*/
public function fetchAssociative(): array|false
{
- return $this->connection->fetchAssociative($this->getSQL(), $this->params, $this->paramTypes);
+ return $this->connection->fetchAssociative($this->getSQL(), $this->params, $this->types);
}
/**
@@ -204,7 +204,7 @@ public function fetchAssociative(): array|false
*/
public function fetchNumeric(): array|false
{
- return $this->connection->fetchNumeric($this->getSQL(), $this->params, $this->paramTypes);
+ return $this->connection->fetchNumeric($this->getSQL(), $this->params, $this->types);
}
/**
@@ -217,7 +217,7 @@ public function fetchNumeric(): array|false
*/
public function fetchOne(): mixed
{
- return $this->connection->fetchOne($this->getSQL(), $this->params, $this->paramTypes);
+ return $this->connection->fetchOne($this->getSQL(), $this->params, $this->types);
}
/**
@@ -229,7 +229,7 @@ public function fetchOne(): mixed
*/
public function fetchAllNumeric(): array
{
- return $this->connection->fetchAllNumeric($this->getSQL(), $this->params, $this->paramTypes);
+ return $this->connection->fetchAllNumeric($this->getSQL(), $this->params, $this->types);
}
/**
@@ -241,7 +241,7 @@ public function fetchAllNumeric(): array
*/
public function fetchAllAssociative(): array
{
- return $this->connection->fetchAllAssociative($this->getSQL(), $this->params, $this->paramTypes);
+ return $this->connection->fetchAllAssociative($this->getSQL(), $this->params, $this->types);
}
/**
@@ -254,7 +254,7 @@ public function fetchAllAssociative(): array
*/
public function fetchAllKeyValue(): array
{
- return $this->connection->fetchAllKeyValue($this->getSQL(), $this->params, $this->paramTypes);
+ return $this->connection->fetchAllKeyValue($this->getSQL(), $this->params, $this->types);
}
/**
@@ -268,7 +268,7 @@ public function fetchAllKeyValue(): array
*/
public function fetchAllAssociativeIndexed(): array
{
- return $this->connection->fetchAllAssociativeIndexed($this->getSQL(), $this->params, $this->paramTypes);
+ return $this->connection->fetchAllAssociativeIndexed($this->getSQL(), $this->params, $this->types);
}
/**
@@ -280,7 +280,7 @@ public function fetchAllAssociativeIndexed(): array
*/
public function fetchFirstColumn(): array
{
- return $this->connection->fetchFirstColumn($this->getSQL(), $this->params, $this->paramTypes);
+ return $this->connection->fetchFirstColumn($this->getSQL(), $this->params, $this->types);
}
/**
@@ -290,7 +290,7 @@ public function fetchFirstColumn(): array
*/
public function executeQuery(): Result
{
- return $this->connection->executeQuery($this->getSQL(), $this->params, $this->paramTypes);
+ return $this->connection->executeQuery($this->getSQL(), $this->params, $this->types);
}
/**
@@ -304,7 +304,7 @@ public function executeQuery(): Result
*/
public function executeStatement(): int|string
{
- return $this->connection->executeStatement($this->getSQL(), $this->params, $this->paramTypes);
+ return $this->connection->executeStatement($this->getSQL(), $this->params, $this->types);
}
/**
@@ -342,19 +342,19 @@ public function getSQL(): string
* ->setParameter('user_id', 1);
*
*
- * @param int|string $key Parameter position or name
- * @param mixed $value Parameter value
- * @param int|string|Type|null $type Parameter type
+ * @param int|string $key Parameter position or name
+ * @param mixed $value Parameter value
+ * @param string|ParameterType|Type|null $type Parameter type
*
* @return $this This QueryBuilder instance.
*/
public function setParameter(
int|string $key,
mixed $value,
- int|string|Type|null $type = ParameterType::STRING
+ string|ParameterType|Type|null $type = ParameterType::STRING
): self {
if ($type !== null) {
- $this->paramTypes[$key] = $type;
+ $this->types[$key] = $type;
} else {
Deprecation::trigger(
'doctrine/dbal',
@@ -383,15 +383,15 @@ public function setParameter(
* ));
*
*
- * @param list