Я хотел бы иметь последний запрос (для целей отладки) из PDOStatement. Но я не могу переопределить методы bindParam и bindValue. Когда я попробовал код ниже, я получил:
Неустранимая ошибка: значение по умолчанию для параметров с подсказкой типа класса может быть только NULL
- Дублирующие записи, созданные на простом INSERT
- Используя pdo query () и пользовательский getValue () на том же объекте базы данных?
- как использовать объект соединения PDO в разных файлах
- PDO FETCH_INTO $ этот класс не работает
- Как писать отчеты о подготовке и выполнении в OOP PDO?
- Попытка создать статический класс базы данных, доступ к которому я могу получить из любой функции вне класса
Затем я заменил PDO::PARAM_STR
на null
в списке параметров bindParam / bindValue, поэтому я получил:
Строгие стандарты: декларация DBStatement :: bindParam () должна быть совместима с параметром PDOStatement :: bindParam ()
Затем я удалил int
перед параметром $data_type
и установил значение по умолчанию для PDO::PARAM_STR
. Затем я получил:
Строгие стандарты: декларация DBStatement :: bindParam () должна быть совместима с строкой PDOStatement :: bindParam () в D: \ www \ pdotest.php в строке 73
(интересно, теперь bindValue в порядке).
Итак, что я могу сделать сейчас?
class DBConnection extends PDO { public function __construct($dsn, $username = null, $password = null, $driver_options = array()) { parent::__construct($dsn, $username, $password, $driver_options); $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('DBStatement', array($this))); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } } class DBException extends PDOException { private $query_string; private $parameters; public function __construct($message = '', $code = 0, $previous = null, $query_string = '', $parameters = array()) { parent::__construct($message, $code, $previous); $this->query_string = $query_string; $this->parameters = $parameters; } public function getQueryString() { return $this->query_string; } public function getParameters() { return $this->parameters; } } class DBStatement extends PDOStatement { private $conn; private $parameters = array(); protected function __construct($conn) { $this->conn = $conn; } public function bindParam($parameter, &$variable, int $data_type = PDO::PARAM_STR, int $length = null, $driver_options = null) { $this->parameters[$parameter] = $variable; parent::bindParam($parameter, $variable, $data_type, $length, $driver_options); } public function bindValue($parameter, $value, int $data_type = PDO::PARAM_STR) { $this->parameters[$parameter] = $value; parent::bindValue($parameter, $value, $data_type); } public function execute($input_parameters = null) { try { parent::execute($input_parameters); } catch (PDOException $e) { throw new DBException($e->getMessage(), $e->getCode(), $e->getPrevious(), $this->queryString, $this->parameters); } } } $id = 1; try { $conn = new DBConnection('mysql:host=localhost;dbname=test', 'root', ''); $stmt = $conn->prepare('select * from foo where id = :id'); $stmt->bindParam(':id', $id); $stmt->execute(); } catch (DBException $e) { echo "Query string was: ".$e->getQueryString()."\n"; echo "Parameters was: ".print_r($e->getParameters(), true); }
Я также получаю следующий запрос, когда я бросаю DBException (из-за параметра $ code):
Примечание. Неверно сформированное числовое значение, встречающееся в D: \ www \ pdotest.php в строке 21
Не нужно использовать тип «int» переменной $ data_type, тогда он работает.
public function bindParam($parameter, &$variable, $data_type = PDO::PARAM_STR, $length = null, $driver_options = null) { $this->parameters[$parameter] = $variable; parent::bindParam($parameter, $variable, $data_type, $length, $driver_options); } public function bindValue($parameter, $value, $data_type = PDO::PARAM_STR) { $this->parameters[$parameter] = $value; parent::bindValue($parameter, $value, $data_type); }
Уведомление, которое вы получаете, похоже, связано с этой нерешенной ошибкой php . Я бы изменил переопределенные bindParam и bindValue, чтобы они были совместимы с объявлением родителя. Если вы хотите установить свои собственные значения параметров по умолчанию, вы можете сделать это в переопределенных методах. Наконец, я просто изменил бы конструкцию исключения, чтобы опустить код:
throw new DBException($e->getMessage(), NULL, $e->getPrevious(), $this->queryString, $this->parameters);