Bicycle/Services/DataBase/Classes/Statement.php
Egor Isaev 9d4edf147a dev
2026-08-07 11:40:03 +03:00

97 lines
3.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* @package Bicycle
* @author Egor Isaev
* @description Statement.php
* @copyright (c) 07/08/2026
*/
namespace Services\DataBase\Classes;
use PDO;
use PDOStatement;
/**
* Расширение PDOStatement, подключается через PDO::ATTR_STATEMENT_CLASS
* (см. PdoDriver::connect()). Добавляет showQuery()/sq() — PDOStatement::debugDumpParams()
* печатает в stdout, а не возвращает строку, поэтому значения bind-параметров
* копятся вручную (bindValue()/execute() переопределены) и подставляются в SQL сами.
*/
class Statement extends PDOStatement
{
/** @var array<int|string,mixed> Значения, забинженные через bindValue()/execute() */
protected array $_bound_params = [];
/**
* Конструктор вызывается только изнутри PDO (PDO::ATTR_STATEMENT_CLASS) — не создавать напрямую.
*
* @param PdoDriver $driver Владелец, нужен для quote() в showQuery()
*/
protected function __construct(protected PdoDriver $driver)
{
}
/**
* @inheritDoc
*/
public function bindValue(int|string $param, mixed $value, int $type = PDO::PARAM_STR): bool
{
$this->_bound_params[$param] = $value;
return parent::bindValue($param, $value, $type);
}
/**
* @inheritDoc
*/
public function execute(?array $params = null): bool
{
foreach ($params ?? [] as $key => $value) {
$this->_bound_params[$key] = $value;
}
return parent::execute($params);
}
/**
* Возвращает SQL с подставленными вместо плейсхолдеров значениями — только для дебага
* (не для реального выполнения: значения квотируются через PDO::quote(), не защищают от всего,
* на что рассчитана честная подготовленная подстановка).
*
* @return string
* @throws \System\Classes\MyException
*/
public function showQuery(): string
{
$sql = $this->queryString;
foreach ($this->_bound_params as $key => $value) {
$quoted = is_int($value) || is_float($value) ? (string) $value : $this->driver->pdo()->quote((string) $value);
if (is_int($key)) {
$pos = strpos($sql, '?');
if ($pos !== false) {
$sql = substr_replace($sql, $quoted, $pos, 1);
}
} else {
$placeholder = str_starts_with((string) $key, ':') ? $key : ':' . $key;
$sql = str_replace($placeholder, $quoted, $sql);
}
}
return $sql;
}
/**
* Алиас showQuery() для быстрого дебага.
*
* @return string
* @throws \System\Classes\MyException
*/
public function sq(): string
{
return $this->showQuery();
}
}