PHP, PDO, последний запрос, bindParam

#php #oop #inheritance #pdo

#php #ооп #наследование #pdo

Вопрос:

Я хотел бы получить последний запрос (для целей отладки) из PDOStatement. Но я не могу переопределить методы bindParam и bindValue. Когда я попробовал приведенный ниже код, я получил:

Неустранимая ошибка: значение по умолчанию для параметров с подсказкой типа класса может быть только NULL

Затем я заменил PDO::PARAM_STR на null в списке параметров bindParam/bindValue, так что я получил:

Строгие стандарты: объявление DBStatement::bindParam() должно быть совместимо с объявлением PDOStatement::bindParam()

Затем я удалил int предшествующий $data_type параметр и установил значение по умолчанию на PDO::PARAM_STR . Затем я получил:

Строгие стандарты: объявление DBStatement::bindParam() должно быть совместимо с объявлением PDOStatement::bindParam() в D:wwwpdotest.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, amp;$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:wwwpdotest.php в строке 21

Комментарии:

1. Да, вы можете проголосовать против этого вопроса, но где ответ? Вы знаете? Пожалуйста, поделитесь этим!

Ответ №1:

Не нужно использовать тип «int» переменной $data_type, тогда это работает.

 public function bindParam($parameter, amp;$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);
}
  

Ответ №2:

Уведомление, которое вы получаете, похоже, связано с этой неразрешенной ошибкой в php. Я бы изменил переопределенные bindParam и bindValue так, чтобы они были совместимы с объявлением родительского элемента. Если вы хотите установить свои собственные значения параметров по умолчанию, вы можете сделать это с помощью переопределенных методов. Наконец, я бы просто изменил конструкцию исключения, чтобы опустить код:

 throw new DBException($e->getMessage(), NULL, $e->getPrevious(), $this->queryString, $this->parameters);