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];
}
}
By default, PDO returns each row as an array indexed by the column name and 0-indexed column position in the row. To request a different return style, specify one of the PDO::FETCH_* constants as the first parameter when you call the PDOStatement::fetch method: PDO::FETCH_ASSOC.
PDO::FETCH_ASSOC. Returns an array indexed by column name as returned in your result set. PDO::FETCH_BOTH (default) Returns an array indexed by both column name and 0-indexed column number as returned in your result set.
Introduction to the PHP fetch() method The fetch() method allows you to fetch a row from a result set associated with a PDOStatement object. Internally, the fetch() method fetches a single row from a result set and moves the internal pointer to the next row in the result set.
Fetch data from a result set by calling one of the following fetch methods: To return a single row from a result set as an array or object, call the PDOStatement::fetch method. To return all of the rows from the result set as an array of arrays or objects, call the PDOStatement::fetchAll method.
I think it should return a stdclass instance so this would be a bug - but would have to look it up in the code to verify. will do if there is no accepted answer till then.
What will work is to use PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE and then provide a class name as first column. While this is a hack:
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
$stmt = $db->query("SELECT 'classname', * FROM `table` WHERE `id` = 1;");
EDIT: As promised here the code. The relevant code is here http://lxr.php.net/xref/PHP_5_4/ext/pdo/pdo_stmt.c#940 So setting the for using fetch() is only possible with FETCH_CLASSTYPE. The alternative is using PDOStatement::fetchObject()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With