updated-packages
This commit is contained in:
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Connection.php
vendored
Normal file
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Connection.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli;
|
||||
|
||||
final class Connection extends MysqliConnection
|
||||
{
|
||||
}
|
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli;
|
||||
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver\AbstractMySQLDriver;
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
|
||||
class Driver extends AbstractMySQLDriver
|
||||
{
|
||||
@@ -13,9 +14,9 @@ class Driver extends AbstractMySQLDriver
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
|
||||
{
|
||||
try {
|
||||
return new MysqliConnection($params, $username, $password, $driverOptions);
|
||||
return new Connection($params, (string) $username, (string) $password, $driverOptions);
|
||||
} catch (MysqliException $e) {
|
||||
throw DBALException::driverException($this, $e);
|
||||
throw Exception::driverException($this, $e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +25,12 @@ class Driver extends AbstractMySQLDriver
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
Deprecation::trigger(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/issues/3580',
|
||||
'Driver::getName() is deprecated'
|
||||
);
|
||||
|
||||
return 'mysqli';
|
||||
}
|
||||
}
|
||||
|
31
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/ConnectionError.php
vendored
Normal file
31
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/ConnectionError.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
|
||||
use mysqli;
|
||||
use mysqli_sql_exception;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class ConnectionError extends MysqliException
|
||||
{
|
||||
public static function new(mysqli $connection): self
|
||||
{
|
||||
return new self($connection->error, $connection->sqlstate, $connection->errno);
|
||||
}
|
||||
|
||||
public static function upcast(mysqli_sql_exception $exception): self
|
||||
{
|
||||
$p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate');
|
||||
$p->setAccessible(true);
|
||||
|
||||
return new self($exception->getMessage(), $p->getValue($exception), $exception->getCode(), $exception);
|
||||
}
|
||||
}
|
36
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/ConnectionFailed.php
vendored
Normal file
36
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/ConnectionFailed.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
|
||||
use mysqli;
|
||||
use mysqli_sql_exception;
|
||||
use ReflectionProperty;
|
||||
|
||||
use function assert;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class ConnectionFailed extends MysqliException
|
||||
{
|
||||
public static function new(mysqli $connection): self
|
||||
{
|
||||
$error = $connection->connect_error;
|
||||
assert($error !== null);
|
||||
|
||||
return new self($error, 'HY000', $connection->connect_errno);
|
||||
}
|
||||
|
||||
public static function upcast(mysqli_sql_exception $exception): self
|
||||
{
|
||||
$p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate');
|
||||
$p->setAccessible(true);
|
||||
|
||||
return new self($exception->getMessage(), $p->getValue($exception), $exception->getCode(), $exception);
|
||||
}
|
||||
}
|
22
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/FailedReadingStreamOffset.php
vendored
Normal file
22
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/FailedReadingStreamOffset.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class FailedReadingStreamOffset extends MysqliException
|
||||
{
|
||||
public static function new(int $offset): self
|
||||
{
|
||||
return new self(sprintf('Failed reading the stream resource for parameter offset %d.', $offset));
|
||||
}
|
||||
}
|
28
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/InvalidOption.php
vendored
Normal file
28
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/InvalidOption.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class InvalidOption extends MysqliException
|
||||
{
|
||||
/**
|
||||
* @param mixed $option
|
||||
* @param mixed $value
|
||||
*/
|
||||
public static function fromOption($option, $value): self
|
||||
{
|
||||
return new self(
|
||||
sprintf('Failed to set option %d with value "%s"', $option, $value)
|
||||
);
|
||||
}
|
||||
}
|
31
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/StatementError.php
vendored
Normal file
31
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/StatementError.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
|
||||
use mysqli_sql_exception;
|
||||
use mysqli_stmt;
|
||||
use ReflectionProperty;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class StatementError extends MysqliException
|
||||
{
|
||||
public static function new(mysqli_stmt $statement): self
|
||||
{
|
||||
return new self($statement->error, $statement->sqlstate, $statement->errno);
|
||||
}
|
||||
|
||||
public static function upcast(mysqli_sql_exception $exception): self
|
||||
{
|
||||
$p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate');
|
||||
$p->setAccessible(true);
|
||||
|
||||
return new self($exception->getMessage(), $p->getValue($exception), $exception->getCode(), $exception);
|
||||
}
|
||||
}
|
25
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/UnknownType.php
vendored
Normal file
25
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Exception/UnknownType.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli\Exception;
|
||||
|
||||
use Doctrine\DBAL\Driver\Mysqli\MysqliException;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class UnknownType extends MysqliException
|
||||
{
|
||||
/**
|
||||
* @param mixed $type
|
||||
*/
|
||||
public static function new($type): self
|
||||
{
|
||||
return new self(sprintf('Unknown type, %d given.', $type));
|
||||
}
|
||||
}
|
@@ -2,18 +2,18 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli;
|
||||
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionFailed;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\InvalidOption;
|
||||
use Doctrine\DBAL\Driver\PingableConnection;
|
||||
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
use mysqli;
|
||||
use const MYSQLI_INIT_COMMAND;
|
||||
use const MYSQLI_OPT_CONNECT_TIMEOUT;
|
||||
use const MYSQLI_OPT_LOCAL_INFILE;
|
||||
use const MYSQLI_READ_DEFAULT_FILE;
|
||||
use const MYSQLI_READ_DEFAULT_GROUP;
|
||||
use const MYSQLI_SERVER_PUBLIC_KEY;
|
||||
use function defined;
|
||||
use mysqli_sql_exception;
|
||||
|
||||
use function assert;
|
||||
use function floor;
|
||||
use function func_get_args;
|
||||
use function in_array;
|
||||
@@ -22,12 +22,21 @@ use function mysqli_errno;
|
||||
use function mysqli_error;
|
||||
use function mysqli_init;
|
||||
use function mysqli_options;
|
||||
use function restore_error_handler;
|
||||
use function set_error_handler;
|
||||
use function sprintf;
|
||||
use function stripos;
|
||||
|
||||
class MysqliConnection implements Connection, PingableConnection, ServerInfoAwareConnection
|
||||
use const MYSQLI_INIT_COMMAND;
|
||||
use const MYSQLI_OPT_CONNECT_TIMEOUT;
|
||||
use const MYSQLI_OPT_LOCAL_INFILE;
|
||||
use const MYSQLI_OPT_READ_TIMEOUT;
|
||||
use const MYSQLI_READ_DEFAULT_FILE;
|
||||
use const MYSQLI_READ_DEFAULT_GROUP;
|
||||
use const MYSQLI_SERVER_PUBLIC_KEY;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link Connection} instead
|
||||
*/
|
||||
class MysqliConnection implements ConnectionInterface, PingableConnection, ServerInfoAwareConnection
|
||||
{
|
||||
/**
|
||||
* Name of the option to set connection flags
|
||||
@@ -38,6 +47,8 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
private $conn;
|
||||
|
||||
/**
|
||||
* @internal The connection can be only instantiated by its driver.
|
||||
*
|
||||
* @param mixed[] $params
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
@@ -57,21 +68,25 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
$socket = $params['unix_socket'] ?? ini_get('mysqli.default_socket');
|
||||
$dbname = $params['dbname'] ?? null;
|
||||
|
||||
$flags = $driverOptions[static::OPTION_FLAGS] ?? null;
|
||||
$flags = $driverOptions[static::OPTION_FLAGS] ?? 0;
|
||||
|
||||
$this->conn = mysqli_init();
|
||||
$conn = mysqli_init();
|
||||
assert($conn !== false);
|
||||
|
||||
$this->conn = $conn;
|
||||
|
||||
$this->setSecureConnection($params);
|
||||
$this->setDriverOptions($driverOptions);
|
||||
|
||||
set_error_handler(static function () {
|
||||
});
|
||||
try {
|
||||
if (! $this->conn->real_connect($params['host'], $username, $password, $dbname, $port, $socket, $flags)) {
|
||||
throw new MysqliException($this->conn->connect_error, $this->conn->sqlstate ?? 'HY000', $this->conn->connect_errno);
|
||||
}
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
$success = @$this->conn
|
||||
->real_connect($params['host'], $username, $password, $dbname, $port, $socket, $flags);
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
throw ConnectionFailed::upcast($e);
|
||||
}
|
||||
|
||||
if (! $success) {
|
||||
throw ConnectionFailed::new($this->conn);
|
||||
}
|
||||
|
||||
if (! isset($params['charset'])) {
|
||||
@@ -120,15 +135,21 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
*/
|
||||
public function requiresQueryForServerVersion()
|
||||
{
|
||||
Deprecation::triggerIfCalledFromOutside(
|
||||
'doctrine/dbal',
|
||||
'https://github.com/doctrine/dbal/pull/4114',
|
||||
'ServerInfoAwareConnection::requiresQueryForServerVersion() is deprecated and removed in DBAL 3.'
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepare($prepareString)
|
||||
public function prepare($sql)
|
||||
{
|
||||
return new MysqliStatement($this->conn, $prepareString);
|
||||
return new Statement($this->conn, $sql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,18 +168,24 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function quote($input, $type = ParameterType::STRING)
|
||||
public function quote($value, $type = ParameterType::STRING)
|
||||
{
|
||||
return "'" . $this->conn->escape_string($input) . "'";
|
||||
return "'" . $this->conn->escape_string($value) . "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exec($statement)
|
||||
public function exec($sql)
|
||||
{
|
||||
if ($this->conn->query($statement) === false) {
|
||||
throw new MysqliException($this->conn->error, $this->conn->sqlstate, $this->conn->errno);
|
||||
try {
|
||||
$result = $this->conn->query($sql);
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
throw ConnectionError::upcast($e);
|
||||
}
|
||||
|
||||
if ($result === false) {
|
||||
throw ConnectionError::new($this->conn);
|
||||
}
|
||||
|
||||
return $this->conn->affected_rows;
|
||||
@@ -187,7 +214,11 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
return $this->conn->commit();
|
||||
try {
|
||||
return $this->conn->commit();
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,11 +226,19 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
*/
|
||||
public function rollBack()
|
||||
{
|
||||
return $this->conn->rollback();
|
||||
try {
|
||||
return $this->conn->rollback();
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function errorCode()
|
||||
{
|
||||
@@ -208,6 +247,10 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function errorInfo()
|
||||
{
|
||||
@@ -222,20 +265,18 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
* @throws MysqliException When one of of the options is not supported.
|
||||
* @throws MysqliException When applying doesn't work - e.g. due to incorrect value.
|
||||
*/
|
||||
private function setDriverOptions(array $driverOptions = [])
|
||||
private function setDriverOptions(array $driverOptions = []): void
|
||||
{
|
||||
$supportedDriverOptions = [
|
||||
MYSQLI_OPT_CONNECT_TIMEOUT,
|
||||
MYSQLI_OPT_LOCAL_INFILE,
|
||||
MYSQLI_OPT_READ_TIMEOUT,
|
||||
MYSQLI_INIT_COMMAND,
|
||||
MYSQLI_READ_DEFAULT_FILE,
|
||||
MYSQLI_READ_DEFAULT_GROUP,
|
||||
MYSQLI_SERVER_PUBLIC_KEY,
|
||||
];
|
||||
|
||||
if (defined('MYSQLI_SERVER_PUBLIC_KEY')) {
|
||||
$supportedDriverOptions[] = MYSQLI_SERVER_PUBLIC_KEY;
|
||||
}
|
||||
|
||||
$exceptionMsg = "%s option '%s' with value '%s'";
|
||||
|
||||
foreach ($driverOptions as $option => $value) {
|
||||
@@ -244,9 +285,7 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
}
|
||||
|
||||
if (! in_array($option, $supportedDriverOptions, true)) {
|
||||
throw new MysqliException(
|
||||
sprintf($exceptionMsg, 'Unsupported', $option, $value)
|
||||
);
|
||||
throw InvalidOption::fromOption($option, $value);
|
||||
}
|
||||
|
||||
if (@mysqli_options($this->conn, $option, $value)) {
|
||||
@@ -267,6 +306,8 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
/**
|
||||
* Pings the server and re-connects when `mysqli.reconnect = 1`
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ping()
|
||||
@@ -277,13 +318,14 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
/**
|
||||
* Establish a secure connection
|
||||
*
|
||||
* @param mixed[] $params
|
||||
* @param array<string,string> $params
|
||||
*
|
||||
* @throws MysqliException
|
||||
*/
|
||||
private function setSecureConnection(array $params)
|
||||
private function setSecureConnection(array $params): void
|
||||
{
|
||||
if (! isset($params['ssl_key']) &&
|
||||
if (
|
||||
! isset($params['ssl_key']) &&
|
||||
! isset($params['ssl_cert']) &&
|
||||
! isset($params['ssl_ca']) &&
|
||||
! isset($params['ssl_capath']) &&
|
||||
@@ -293,11 +335,11 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
|
||||
}
|
||||
|
||||
$this->conn->ssl_set(
|
||||
$params['ssl_key'] ?? null,
|
||||
$params['ssl_cert'] ?? null,
|
||||
$params['ssl_ca'] ?? null,
|
||||
$params['ssl_capath'] ?? null,
|
||||
$params['ssl_cipher'] ?? null
|
||||
$params['ssl_key'] ?? '',
|
||||
$params['ssl_cert'] ?? '',
|
||||
$params['ssl_ca'] ?? '',
|
||||
$params['ssl_capath'] ?? '',
|
||||
$params['ssl_cipher'] ?? ''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,9 @@ namespace Doctrine\DBAL\Driver\Mysqli;
|
||||
use Doctrine\DBAL\Driver\AbstractDriverException;
|
||||
|
||||
/**
|
||||
* Exception thrown in case the mysqli driver errors.
|
||||
* @deprecated Use {@link \Doctrine\DBAL\Driver\Exception} instead
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class MysqliException extends AbstractDriverException
|
||||
{
|
||||
|
@@ -2,30 +2,45 @@
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli;
|
||||
|
||||
use Doctrine\DBAL\Driver\Statement;
|
||||
use Doctrine\DBAL\Driver\FetchUtils;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\FailedReadingStreamOffset;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\StatementError;
|
||||
use Doctrine\DBAL\Driver\Mysqli\Exception\UnknownType;
|
||||
use Doctrine\DBAL\Driver\Result;
|
||||
use Doctrine\DBAL\Driver\Statement as StatementInterface;
|
||||
use Doctrine\DBAL\Driver\StatementIterator;
|
||||
use Doctrine\DBAL\Exception\InvalidArgumentException;
|
||||
use Doctrine\DBAL\FetchMode;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use IteratorAggregate;
|
||||
use mysqli;
|
||||
use mysqli_sql_exception;
|
||||
use mysqli_stmt;
|
||||
use PDO;
|
||||
use stdClass;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
use function array_combine;
|
||||
use function array_fill;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function feof;
|
||||
use function fread;
|
||||
use function get_resource_type;
|
||||
use function is_array;
|
||||
use function is_int;
|
||||
use function is_resource;
|
||||
use function sprintf;
|
||||
use function str_repeat;
|
||||
|
||||
class MysqliStatement implements IteratorAggregate, Statement
|
||||
/**
|
||||
* @deprecated Use {@link Statement} instead
|
||||
*/
|
||||
class MysqliStatement implements IteratorAggregate, StatementInterface, Result
|
||||
{
|
||||
/** @var string[] */
|
||||
protected static $_paramTypeMap = [
|
||||
ParameterType::ASCII => 's',
|
||||
ParameterType::STRING => 's',
|
||||
ParameterType::BINARY => 's',
|
||||
ParameterType::BOOLEAN => 'i',
|
||||
@@ -40,11 +55,11 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
/** @var mysqli_stmt */
|
||||
protected $_stmt;
|
||||
|
||||
/** @var string[]|bool|null */
|
||||
/** @var string[]|false|null */
|
||||
protected $_columnNames;
|
||||
|
||||
/** @var mixed[]|null */
|
||||
protected $_rowBindedValues;
|
||||
/** @var mixed[] */
|
||||
protected $_rowBindedValues = [];
|
||||
|
||||
/** @var mixed[] */
|
||||
protected $_bindedValues;
|
||||
@@ -70,6 +85,8 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
private $result = false;
|
||||
|
||||
/**
|
||||
* @internal The statement can be only instantiated by its driver connection.
|
||||
*
|
||||
* @param string $prepareString
|
||||
*
|
||||
* @throws MysqliException
|
||||
@@ -77,16 +94,20 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
public function __construct(mysqli $conn, $prepareString)
|
||||
{
|
||||
$this->_conn = $conn;
|
||||
$this->_stmt = $conn->prepare($prepareString);
|
||||
if ($this->_stmt === false) {
|
||||
throw new MysqliException($this->_conn->error, $this->_conn->sqlstate, $this->_conn->errno);
|
||||
|
||||
try {
|
||||
$stmt = $conn->prepare($prepareString);
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
throw ConnectionError::upcast($e);
|
||||
}
|
||||
|
||||
$paramCount = $this->_stmt->param_count;
|
||||
if (0 >= $paramCount) {
|
||||
return;
|
||||
if ($stmt === false) {
|
||||
throw ConnectionError::new($this->_conn);
|
||||
}
|
||||
|
||||
$this->_stmt = $stmt;
|
||||
|
||||
$paramCount = $this->_stmt->param_count;
|
||||
$this->types = str_repeat('s', $paramCount);
|
||||
$this->_bindedValues = array_fill(1, $paramCount, null);
|
||||
}
|
||||
@@ -94,20 +115,16 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null)
|
||||
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null)
|
||||
{
|
||||
if ($type === null) {
|
||||
$type = 's';
|
||||
} else {
|
||||
if (! isset(self::$_paramTypeMap[$type])) {
|
||||
throw new MysqliException(sprintf("Unknown type: '%s'", $type));
|
||||
}
|
||||
assert(is_int($param));
|
||||
|
||||
$type = self::$_paramTypeMap[$type];
|
||||
if (! isset(self::$_paramTypeMap[$type])) {
|
||||
throw UnknownType::new($type);
|
||||
}
|
||||
|
||||
$this->_bindedValues[$column] =& $variable;
|
||||
$this->types[$column - 1] = $type;
|
||||
$this->_bindedValues[$param] =& $variable;
|
||||
$this->types[$param - 1] = self::$_paramTypeMap[$type];
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -117,19 +134,15 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
*/
|
||||
public function bindValue($param, $value, $type = ParameterType::STRING)
|
||||
{
|
||||
if ($type === null) {
|
||||
$type = 's';
|
||||
} else {
|
||||
if (! isset(self::$_paramTypeMap[$type])) {
|
||||
throw new MysqliException(sprintf("Unknown type: '%s'", $type));
|
||||
}
|
||||
assert(is_int($param));
|
||||
|
||||
$type = self::$_paramTypeMap[$type];
|
||||
if (! isset(self::$_paramTypeMap[$type])) {
|
||||
throw UnknownType::new($type);
|
||||
}
|
||||
|
||||
$this->_values[$param] = $value;
|
||||
$this->_bindedValues[$param] =& $this->_values[$param];
|
||||
$this->types[$param - 1] = $type;
|
||||
$this->types[$param - 1] = self::$_paramTypeMap[$type];
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -139,31 +152,35 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
*/
|
||||
public function execute($params = null)
|
||||
{
|
||||
if ($this->_bindedValues !== null) {
|
||||
if ($params !== null) {
|
||||
if (! $this->_bindValues($params)) {
|
||||
throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
|
||||
}
|
||||
} else {
|
||||
[$types, $values, $streams] = $this->separateBoundValues();
|
||||
if (! $this->_stmt->bind_param($types, ...$values)) {
|
||||
throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
|
||||
}
|
||||
$this->sendLongData($streams);
|
||||
if ($params !== null && count($params) > 0) {
|
||||
if (! $this->bindUntypedValues($params)) {
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
} elseif (count($this->_bindedValues) > 0) {
|
||||
$this->bindTypedParameters();
|
||||
}
|
||||
|
||||
if (! $this->_stmt->execute()) {
|
||||
throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
|
||||
try {
|
||||
$result = $this->_stmt->execute();
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
throw StatementError::upcast($e);
|
||||
}
|
||||
|
||||
if (! $result) {
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
|
||||
if ($this->_columnNames === null) {
|
||||
$meta = $this->_stmt->result_metadata();
|
||||
if ($meta !== false) {
|
||||
$fields = $meta->fetch_fields();
|
||||
assert(is_array($fields));
|
||||
|
||||
$columnNames = [];
|
||||
foreach ($meta->fetch_fields() as $col) {
|
||||
foreach ($fields as $col) {
|
||||
$columnNames[] = $col->name;
|
||||
}
|
||||
|
||||
$meta->free();
|
||||
|
||||
$this->_columnNames = $columnNames;
|
||||
@@ -180,7 +197,7 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
// Bind row values _after_ storing the result. Otherwise, if mysqli is compiled with libmysql,
|
||||
// it will have to allocate as much memory as it may be needed for the given column type
|
||||
// (e.g. for a LONGBLOB field it's 4 gigabytes)
|
||||
// (e.g. for a LONGBLOB column it's 4 gigabytes)
|
||||
// @link https://bugs.php.net/bug.php?id=51386#1270673122
|
||||
//
|
||||
// Make sure that the values are bound after each execution. Otherwise, if closeCursor() has been
|
||||
@@ -197,7 +214,7 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
}
|
||||
|
||||
if (! $this->_stmt->bind_result(...$refs)) {
|
||||
throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,17 +224,16 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
}
|
||||
|
||||
/**
|
||||
* Split $this->_bindedValues into those values that need to be sent using mysqli::send_long_data()
|
||||
* and those that can be bound the usual way.
|
||||
*
|
||||
* @return array<int, array<int|string, mixed>|string>
|
||||
* Binds parameters with known types previously bound to the statement
|
||||
*/
|
||||
private function separateBoundValues()
|
||||
private function bindTypedParameters(): void
|
||||
{
|
||||
$streams = $values = [];
|
||||
$types = $this->types;
|
||||
|
||||
foreach ($this->_bindedValues as $parameter => $value) {
|
||||
assert(is_int($parameter));
|
||||
|
||||
if (! isset($types[$parameter - 1])) {
|
||||
$types[$parameter - 1] = static::$_paramTypeMap[ParameterType::STRING];
|
||||
}
|
||||
@@ -225,39 +241,48 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
if ($types[$parameter - 1] === static::$_paramTypeMap[ParameterType::LARGE_OBJECT]) {
|
||||
if (is_resource($value)) {
|
||||
if (get_resource_type($value) !== 'stream') {
|
||||
throw new InvalidArgumentException('Resources passed with the LARGE_OBJECT parameter type must be stream resources.');
|
||||
throw new InvalidArgumentException(
|
||||
'Resources passed with the LARGE_OBJECT parameter type must be stream resources.'
|
||||
);
|
||||
}
|
||||
|
||||
$streams[$parameter] = $value;
|
||||
$values[$parameter] = null;
|
||||
continue;
|
||||
} else {
|
||||
$types[$parameter - 1] = static::$_paramTypeMap[ParameterType::STRING];
|
||||
}
|
||||
|
||||
$types[$parameter - 1] = static::$_paramTypeMap[ParameterType::STRING];
|
||||
}
|
||||
|
||||
$values[$parameter] = $value;
|
||||
}
|
||||
|
||||
return [$types, $values, $streams];
|
||||
if (! $this->_stmt->bind_param($types, ...$values)) {
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
|
||||
$this->sendLongData($streams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle $this->_longData after regular query parameters have been bound
|
||||
*
|
||||
* @param array<int, resource> $streams
|
||||
*
|
||||
* @throws MysqliException
|
||||
*/
|
||||
private function sendLongData($streams)
|
||||
private function sendLongData(array $streams): void
|
||||
{
|
||||
foreach ($streams as $paramNr => $stream) {
|
||||
while (! feof($stream)) {
|
||||
$chunk = fread($stream, 8192);
|
||||
|
||||
if ($chunk === false) {
|
||||
throw new MysqliException("Failed reading the stream resource for parameter offset ${paramNr}.");
|
||||
throw FailedReadingStreamOffset::new($paramNr);
|
||||
}
|
||||
|
||||
if (! $this->_stmt->send_long_data($paramNr - 1, $chunk)) {
|
||||
throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,7 +295,7 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function _bindValues($values)
|
||||
private function bindUntypedValues(array $values)
|
||||
{
|
||||
$params = [];
|
||||
$types = str_repeat('s', count($values));
|
||||
@@ -283,11 +308,17 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]|false
|
||||
* @return mixed[]|false|null
|
||||
*
|
||||
* @throws StatementError
|
||||
*/
|
||||
private function _fetch()
|
||||
{
|
||||
$ret = $this->_stmt->fetch();
|
||||
try {
|
||||
$ret = $this->_stmt->fetch();
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
throw StatementError::upcast($e);
|
||||
}
|
||||
|
||||
if ($ret === true) {
|
||||
$values = [];
|
||||
@@ -303,6 +334,8 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchNumeric(), fetchAssociative() or fetchOne() instead.
|
||||
*/
|
||||
public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
|
||||
{
|
||||
@@ -319,36 +352,32 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
}
|
||||
|
||||
$values = $this->_fetch();
|
||||
|
||||
if ($values === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($values === false) {
|
||||
throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno);
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
|
||||
switch ($fetchMode) {
|
||||
case FetchMode::NUMERIC:
|
||||
return $values;
|
||||
if ($fetchMode === FetchMode::NUMERIC) {
|
||||
return $values;
|
||||
}
|
||||
|
||||
assert(is_array($this->_columnNames));
|
||||
$assoc = array_combine($this->_columnNames, $values);
|
||||
assert(is_array($assoc));
|
||||
|
||||
switch ($fetchMode) {
|
||||
case FetchMode::ASSOCIATIVE:
|
||||
return array_combine($this->_columnNames, $values);
|
||||
return $assoc;
|
||||
|
||||
case FetchMode::MIXED:
|
||||
$ret = array_combine($this->_columnNames, $values);
|
||||
$ret += $values;
|
||||
|
||||
return $ret;
|
||||
return $assoc + $values;
|
||||
|
||||
case FetchMode::STANDARD_OBJECT:
|
||||
$assoc = array_combine($this->_columnNames, $values);
|
||||
$ret = new stdClass();
|
||||
|
||||
foreach ($assoc as $column => $value) {
|
||||
$ret->$column = $value;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
return (object) $assoc;
|
||||
|
||||
default:
|
||||
throw new MysqliException(sprintf("Unknown fetch type '%s'", $fetchMode));
|
||||
@@ -357,6 +386,8 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead.
|
||||
*/
|
||||
public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
|
||||
{
|
||||
@@ -379,6 +410,8 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use fetchOne() instead.
|
||||
*/
|
||||
public function fetchColumn($columnIndex = 0)
|
||||
{
|
||||
@@ -391,6 +424,82 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
return $row[$columnIndex] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*/
|
||||
public function fetchNumeric()
|
||||
{
|
||||
// do not try fetching from the statement if it's not expected to contain the result
|
||||
// in order to prevent exceptional situation
|
||||
if (! $this->result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$values = $this->_fetch();
|
||||
|
||||
if ($values === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($values === false) {
|
||||
throw StatementError::new($this->_stmt);
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function fetchAssociative()
|
||||
{
|
||||
$values = $this->fetchNumeric();
|
||||
|
||||
if ($values === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(is_array($this->_columnNames));
|
||||
$row = array_combine($this->_columnNames, $values);
|
||||
assert(is_array($row));
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchOne()
|
||||
{
|
||||
return FetchUtils::fetchOne($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllNumeric(): array
|
||||
{
|
||||
return FetchUtils::fetchAllNumeric($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAllAssociative(): array
|
||||
{
|
||||
return FetchUtils::fetchAllAssociative($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchFirstColumn(): array
|
||||
{
|
||||
return FetchUtils::fetchFirstColumn($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -401,6 +510,10 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated The error information is available via exceptions.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function errorInfo()
|
||||
{
|
||||
@@ -409,11 +522,12 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use free() instead.
|
||||
*/
|
||||
public function closeCursor()
|
||||
{
|
||||
$this->_stmt->free_result();
|
||||
$this->result = false;
|
||||
$this->free();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -438,8 +552,16 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
return $this->_stmt->field_count;
|
||||
}
|
||||
|
||||
public function free(): void
|
||||
{
|
||||
$this->_stmt->free_result();
|
||||
$this->result = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use one of the fetch- or iterate-related methods.
|
||||
*/
|
||||
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
|
||||
{
|
||||
@@ -450,7 +572,10 @@ class MysqliStatement implements IteratorAggregate, Statement
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated Use iterateNumeric(), iterateAssociative() or iterateColumn() instead.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new StatementIterator($this);
|
||||
|
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Statement.php
vendored
Normal file
7
vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Statement.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\DBAL\Driver\Mysqli;
|
||||
|
||||
final class Statement extends MysqliStatement
|
||||
{
|
||||
}
|
Reference in New Issue
Block a user