48

I am learning pdo in php , so as to make database access easier and more efficient .One explanation i have read for fetch _class is that The properties of your object are set BEFORE the constructor is called.What does this mean? Any direction is greatly appreciated.

Your Common Sense
158k42 gold badges226 silver badges371 bronze badges
asked Feb 28, 2011 at 0:15
2

4 Answers 4

53

This means that when using PDO to return a result into a custom object, you are required to set out the member variables which correspond to the query result keys.

such as:

class User
{
 //Predefine Here
 public $id;
 public $username;
 public $password;
 public $email;
 public $hash;
 public function profileLink()
 {
 return sprintf('<a href="/profile/%s">%s</a>',$this->id,$this->username);
 }
}
$result = $sth->fetchAll(PDO::FETCH_CLASS, "User");
foreach($result as $user)
{
 echo $user->profileLink();
}

This way PDO can set the variables to the object outside of its internal scope.

if your user class was like so:

class User
{
}

then PDO Would not be able to set the values from outside the scope, as there are no properties defined.

ruleboy21
6,5015 gold badges23 silver badges37 bronze badges
answered Feb 28, 2011 at 0:22

5 Comments

And I am guessing this means if you setup your class with getters and setters, private vars, you can't use PDO::FETCH_CLASS ?
I think getters and setters should get invoked fine (untested)
Yes you can still use private vars. FETCH_CLASS will assign results to private variables.
@RobertPitt - take a look at PDO::FETCH_LAZY constant as well re: getters/setters - as the columns are found they're assigned respectively. I'm sure there's a performance hit as it's all dynamic and it's better to KNOW what you're querying / asking for in advance for others to use your D.R.Y. code as an API later.
as @Kris pointed out they don't have to be public. I don't think they have to be declared at all, so your second example of just declaring the class would work fine. Its obviously not suggested since it makes your code useless to view, but it works.
36

Say you have this snippit of code

<?php
class Foo {
 public $bar;
 public function __construct()
 {
 $this->bar = 1;
 }
}
$stmt = $dbh->prepare("SELECT bar FROM foo");
$stmt->setFetchMode(PDO::FETCH_CLASS, 'Foo'); 
$stmt->execute();
$obj = $stmt->fetch()
?>

The bar propery for $obj will be set to "1" not what is retreived from the database.

If you would like it to be set to the result from the database instead of "1" you can change the fetch mode to

$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'Foo'); 

This causes the constructor to be called before assigning the results to the properties

answered Jun 9, 2012 at 15:58

Comments

3

Instead of using: FetchAll(PDO::FETCH_CLASS, 'classname') You can use: fetchObject('classname')

Example:

class Car extends DatabaseTable {
const TABLE_NAME = 'cars';
// Table Columns
private $color;
private $brand;
private $type;
public function __construct($pdo, $id = false)
{
 parent::__construct($pdo, TABLE_NAME, $id);
}
public static function getAll($pdo, $order = 'id') {
 $query = 'SELECT * FROM ' . self::TABLE_NAME . ' 
 ORDER BY ' . $order;
 $statement = $pdo->prepare($query);
 $objects = [];
 while ($obj = $statement->fetchObject(self::class, [$pdo])) {
 $objects[$obj->getId()] = $obj;
 }
 return $objects;
}

The parent Constructor just sets its 3 properties like: $this->id = $id;

answered Jun 14, 2018 at 9:43

Comments

2

Looking back at PDO::FETCH_CLASS, you don't really need to define the variables as public nor private (as of PHP 7.0 ) , you could define an empty class and PHP PDO will populate the attributes as $Class->attribute even if they are not defined.

this is very useful because you can reuse classes with multiple queries that treat the same table but might return different columns

answered Mar 9, 2016 at 16:51

2 Comments

I recall reading somewhere that setting/getting an instance's properties is a lot slower in PHP if you're doing it on a class that doesn't define the property in question versus one that does (I can't currently find the link though). If dealing with a huge amount of such objects the performance impact could be significant. Plus may IDEs have type-hinting facilities that would not function without a defined property.
I know this is an old answer, but if someone else reads it: "but might return different columns" - That's a massive anti pattern. When you get a class, you should know what properties it has or you would need to make a bunch of property_exists() and similar all over your code.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.