Using PDO::setAttribute, how do I provide the class name when setting PDO::ATTR_DEFAULT_FETCH_MODE to PDO::FETCH_CLASS.
This is the code I am using.. I would like to set it so all of my rows are returned as an instance of DB_Row:
class DB_Row extends ArrayObject {}
$db = new PDO('mysql:dbname=example;host=localhost', 'user', 'pass');
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_CLASS);
$stmt = $db->query("SELECT * FROM `table` WHERE `id` = 1;");
$row = $stmt->fetch(); // I want a DB_Row by default!
The code above results in a PDOException since the DB_Row class name was not assigned.
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: No fetch class specified
How would I go about this?
Thanks in advance..
SOLUTION: I used fireeyedboy‘s answer. It worked the best for my situation as I was already extending PDOStatement for logging purposes…
class DB extends PDO {
public function __construct($host = null, $user = null, $pass = null, $db = null) {
try {
parent::__construct('mysql:dbname=' . $name .';host=' . $host, $user, $pass);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_CLASS);
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('DB_Query', array('DB_Row')));
} catch (PDOException $e) {
die('Database Error');
}
}
}
class DB_Query extends PDOStatement {
private $class;
protected function __construct ($class = 'DB_Row') {
$this->class = $class;
$this->setFetchMode(PDO::FETCH_CLASS, $this->class);
}
}
class DB_Row extends ArrayObject {
public function __set($name, $val) {
$this[$name] = $val;
}
public function __get($name) {
return $this[$name];
}
}
Another kind of hack would be to extend
PDOStatement, override its fetch methods and let yourPDOinstance use that as the default statement class.As an example I’ll just demonstrate overriding
fetch()1 and leavefetchAll()and what have you up to you, if you wanna go this route:This has the added benefit that you’ll only have to define your
PDO::FETCH_CLASSonce in your application, and not in every query.1) I’m surprised PHP didn’t complain about overriding the signature of the method by the way.