Расширение класса операторов PDO - PullRequest
18 голосов
/ 07 августа 2010

Можно ли расширить класс операторов PHP PDO для добавления в него пользовательских методов? Это будет отличаться от расширения базового класса PDO. Если это так, как можно поступить так, поскольку класс операторов возвращается только при выполнении запросов через класс PDO?

Ответы [ 4 ]

25 голосов
/ 07 августа 2010

Вы можете установить класс с помощью PDO::setAttribute():

PDO :: ATTR_STATEMENT_CLASS: Установить предоставленный пользователем класс операторов, полученный из PDOStatement.Не может использоваться с постоянными экземплярами PDO.Требуется массив (строка classname, array (mixed constructor_args)).

Пример:

$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Custom', array($pdo)));
2 голосов
/ 29 мая 2014

Ответ на этот вопрос пользователь в руководстве по PHP под PDO:

class Database extends PDO {
    function __construct($dsn, $username="", $password="", $driver_options=array()) {
        parent::__construct($dsn,$username,$password, $driver_options);
        $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('DBStatement', array($this)));
    }
}
class DBStatement extends PDOStatement {
    public $dbh;
    protected function __construct($dbh) {
        $this->dbh = $dbh;
    }
}

Вы можете найти его оригинальный ответ, выполнив поиск: 'smileaf' на этой странице: https://php.net/manual/en/book.pdo.php

1 голос
/ 19 июля 2014

Это мой код для сохранения результата запроса select в текстовый файл как оператор вставки. Сначала я расширяю класс PDOStatement для добавления пользовательского метода saveResultAsInsertStatement :

<?php
class MyPDOStatement extends PDOStatement {
    protected $pdo;

    protected function __construct($pdo) {
        $this->pdo = $pdo;
    }
    public function saveResultAsInsertStatement($filename) {
        $result = '';
        $columnData = $this->fetchAll(PDO::FETCH_ASSOC);
        if ($columnData != null) {
            $fieldCount = count($columnData[0]);
            $rowsCount = count($columnData);
            $columnsName = array_keys($columnData[0]);
            $result = "INSERT INTO %s ( \n";
            $result .= join(",\n", $columnsName);
            $result .= ") VALUES\n";
            $r = 0;
            foreach ($columnData as $row) {
                $result .= "(";
                $c = 0;
                foreach ($row as $key => $field) {
                    $result .= $this->pdo->quote($field);
                    $result .= ( ++$c < $fieldCount) ? ', ' : '';
                }
                $result .= ")";
                $result .= ( ++$r < $rowsCount) ? ',' : '';
                $result .= "\n";
            }
        }

        $f = fopen($filename, "w");
        fwrite($f, $result);
        fclose($f);
    }

}
?>

Затем я расширяю класс PDO, чтобы установить атрибут PDO :: ATTR_STATEMENT_CLASS

<?php
class MyPDO extends PDO {
    public function __construct(... PDO constructor parameters here ... ) {
        parent::__construct( ... PDO construct parameters here ...);
        $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('MyPDOStatement', array($this)));
    }

}
?>

Итак, я могу написать:

<?php
$conn = new MyPDO(... PDO constructor parameters here ...);

$sql = ... your select statement here...

$conn->query($sql)->saveResultAsInsertStatement(... name of the file here ...);


?>
0 голосов
/ 11 июля 2019

Если вы используете пространства имен для своих классов, вам необходимо добавить обратную косую черту в строку класса.

Без пространства имен:

$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Custom', array($pdo)));

пространство имен:

$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Namespace\Custom', array($pdo)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...