i came across a piece of code where PDO::FETCH_CLASS is being called without passing the name of the class as a parameter, like this:
function getUsers() {
$DBH = $this->getDbh();
$query = "SELECT * FROM users";
try {
$STH = $DBH->query($query);
$users = $STH->fetchAll(PDO::FETCH_CLASS);
} catch(PDOException $e) {
}
return $users;
}
now, in the official documentation it says:
If fetch_style includes PDO::FETCH_CLASSTYPE (e.g. PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE) then the name of the class is determined from a value of the first column.
so im not sure i understood exactly what they mean nor how it works.
let's say i have users table with one record
so how can PDO::FETCH_CLASS know what's the class name? can i add column to my record with the class name in a way FETCH_CLASS will get the class name from the database? example of record structure will be highly appreciated ...thx
*I am testing this class but not the author so changing the class is irrelevant
For fetchAll method, if classname is not supplied and PDO::FETCH_CLASSTYPE flag is not raised, a stdClass object is returned (just like with PDO::FETCH_OBJ). This is what happens (lxr):
1436 switch(how & ~PDO_FETCH_FLAGS) {
1437 case PDO_FETCH_CLASS:
1438 switch(ZEND_NUM_ARGS()) {
1439 case 0:
1440 case 1:
1441 stmt->fetch.cls.ce = zend_standard_class_def;
1442 break
Then, in do_fetch, as there's no class name supplied, this value remains as is. That makes sense, as stdClass is sometimes considered an anonymous class of a sort. )
That explains the code you have to deal with; @eggyal's answer explains how one can use PDO::FETCH_CLASS || PDO::FETCH_CLASSTYPE combo. It's actually a pretty powerful technique, allowing you to skip the boilerplate switch in factory methods.
im not sure i understood exactly what they mean nor how it works
What they mean is that instead of
$STH = $DBH->query("SELECT * FROM users");
$users = $STH->fetchAll(PDO::FETCH_CLASS, 'UserClass');
you can do the following:
$STH = $DBH->query("SELECT 'UserClass', users.* FROM users");
$users = $STH->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
However, this is not especially useful: why hardcode the class name into the SQL only to have MySQL return it with every record and PDO parse each of those fields (i.e. for each record) when instantiating the resultant objects? Better just to specify the class name as the second argument to fetchAll(), as shown in the first example above.
should i add column to my record with the class name?
Well, indeed, one could do that too—and that is a far more useful use of this functionality: it enables the class of each resultant object to depend upon the record itself, which may be useful in some cases (i.e. where not all records in a resultset are of the same "type"—for example: perhaps some records should instantiate Employee objects, whilst others should instantiate Customer objects).
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