Можно ли расширить класс операторов PHP PDO, чтобы добавить к нему специальные методы? Это будет отличаться от расширения базового класса PDO. Если да, то как это сделать, поскольку класс оператора возвращается только при выполнении запросов через класс PDO?
Расширение класса Statement PDO
Ответ 1
Вы можете установить класс PDO::setAttribute()
:
PDO:: ATTR_STATEMENT_CLASS: задайте класс операторов, созданный пользователем, полученный из PDOStatement. Не может использоваться с постоянными экземплярами PDO. Требуется массив (string classname, array (mixed constructor_args)).
Пример:
$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Custom', array($pdo)));
Ответ 2
На это отвечает пользователь в Руководстве по 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
Ответ 3
Это мой код, чтобы сохранить результат запроса select в текстовый файл в качестве инструкции insert. Сначала я расширяю класс PDOStatement для добавления настраиваемого метода saveResultAsInertertatement:
<?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 ...);
?>
Ответ 4
Если вы используете пространства имен для ваших классов, вам нужно добавить обратную косую черту в строку класса.
Без пространства имен:
$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Custom', array($pdo)));
С пространством имен:
$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Namespace\Custom', array($pdo)));