Est-il possible d'étendre la classe d'instruction PHP PDO pour y ajouter des méthodes personnalisées? Cela serait différent de l'extension de la classe PDO de base. Si tel est le cas, comment le ferait-on puisque la classe statement n'est renvoyée que lors de l'exécution de requêtes via la classe PDO?Extension de l'instruction PDO Classe
Répondre
Vous pouvez définir la classe avec PDO::setAttribute()
:
PDO :: ATTR_STATEMENT_CLASS: Définit la classe de l'instruction fournie par l'utilisateur dérivé de PDOStatement. Ne peut pas être utilisé avec des instances PDO persistantes. Requiert array (chaîne classname, array (mixed constructor_args)).
Exemple:
$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Custom', array($pdo)));
Cette réponse par un utilisateur dans le manuel PHP sous AOP:
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;
}
}
Vous pouvez trouver sa réponse originale en effectuant une recherche: 'smileaf' à cette page : https://php.net/manual/en/book.pdo.php
Ceci est mon code pour enregistrer le résultat d'une requête de sélection dans un fichier texte en tant qu'instruction d'insertion. Je tiens d'abord la classe PDOStatement ajouter la méthode personnalisée 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);
}
}
?>
J'étendez la classe PDO pour définir l'attribut 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)));
}
}
?>
Alors, je peut écrire:
<?php
$conn = new MyPDO(... PDO constructor parameters here ...);
$sql = ... your select statement here...
$conn->query($sql)->saveResultAsInsertStatement(... name of the file here ...);
?>
Notez que le constructeur par défaut ne prend pas de rguments (donc non 'array ($ pdo)' là). De plus, pour une utilisation dans un espace de nommage, vous pouvez utiliser 'Custom :: class' au lieu de' 'Custom'' qui vous donne le nom de la classe complète en respectant les imports 'use' actuels. – bodo