Pdo PHP Fetch Class

PDO PHP Fetch Class

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.

PDO class extends and fetch class in PHP

A good question.

For PDO, a class hierarchy doesn't actually matter. What PDO is doing is simply taking columns from database and assigning them to class properties, regardless of the class definition or inheritance.

  • If a property doesn't exist, PDO will try to create it.
  • If there is a property for which there is no column to map - then PDO will leave it alone.

As simple as that. So, it should create anything you select from the database.

As of the particular code you had in your question before - you have to debug it. Look, to see if anything was fetched, you are using whatever method printNickName(). But there could be any error either with this method or any intermediate process. Let me suggest you to create just empty classes, fetch your data in them, and check the properties directly.

After you make sure that all the properties are properly set, you may try with your custom class definitions. To debug the returned data I'd suggest to use

$stmt->execute();
var_dump($stmt->fetchAll(PDO::FETCH_CLASS, 'User'));

You may learn other details of PDO class handling from my article, Fetching objects with PDO

PDO - FETCH_CLASS - pass results to constructor as parameters

[I edited this answer as my previous answer is not accurate anymore.]

FETCH_CLASS does fetch into private properties. Please refer to this answer.

How to fetch data with PDO into class with enum property?

You can't do it with fetchObject(). The reason is that you can't assign int to a property of type UserType. You can use a magic method __set(), but you would have to not declare the property (this is highly not recommended).

You can use __set with lazy property initialization and PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE. If that's confusing for you, this is because it is confusing.

enum UserType:int {
case Master = 1;
case Admin = 2;
case Manager = 3;
}

class User
{
private int $id;
private string $name;
private UserType $userType;

public function __construct()
{
// unset it for lazy initialization (PDO will call __set method instead)
unset($this->userType);
}

public function __set($key, $value)
{
if ($key === 'userType') {
$this->userType = UserType::from($value);
}
}
}

// Tell PDO to call constructor first,
// then try to assign the property if it exists or call magic method __set()
$stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, User::class);
$user = $stmt->fetch();

It might be easier to just stick to doing this in the constructor. You could then fetch the row as an associative array and unpack it into the constructor.

class User
{
private UserType $userType;

public function __construct(private int $id, private string $name, int $userType)
{
$this->userType = UserType::from($userType);
}
}

Then your fetchObject() would look like:

public function fetchObject($sql, array $args = [], string $class_name = "stdClass"): ?object
{
$stmt = self::$instance->prepare($sql);
$stmt->execute($args ?: null);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row ? new $class_name(...$row) : null;
}

You need to unpack the row because PDO doesn't have the capability to pass values to the constructor.

PDO Fetch Class as a grouped collection object rather than as individual objects in an array

My opinion is that you are probably better off using your current array of objects. However, you may be able to fetch into an existing object and have a magic __set() method to append the values to a named array:

class Collection {

public function __set($name, $value) {
$this->$name[] = $value
}
}

PDO::FETCH_INTO won't work with fetchAll as far as I know, so you need a while:

$collection = new Core\Database\Collection;
$statement->setFetchMode(PDO::FETCH_INTO, $collection);
$statement->execute();
while($statement->fetch()){}
return $collection;

Should return something like:

object(Core\Database\Collection)#1 (2) {
["id"]=>
array(2) {
[0]=>string(1) "1",
[1]=>string(1) "2"
}
["title"]=>
array(2) {
[0]=>string(34) "What is your favourite video game?",
[1]=>string(28) "What is your favourite food?"
}
}

Really the only other possibility is to have an object as you show in your edited example, with a property that is an array of objects. You would do this similar to what you have. Just fetch an array of objects of class someNamespace\Question and assign it to a property of another object of class Core\Database\Collection:

$collection = new Core\Database\Collection;
$statement->setFetchMode(PDO::FETCH_CLASS, 'someNamespace\Question');
$statement->execute();
$collection->all = $statement->fetchAll();
return $collection;

Should return something like:

object(Core\Database\Collection)#1 (1) {
["all"]=> array(2) {
[0]=>
object(someNamespace\Question)#1 (2) {
["id"]=>
string(1) "1"
["title"]=>
string(34) "What is your favourite video game?"
}
[1]=>
object(someNamespace\Question)#2 (2) {
["id"]=>
string(1) "2"
["title"]=>
string(28) "What is your favourite food?"
}
}
}

I don't know Laravel and the object/array syntax in the video seems to be homegrown so it's kind of hard to decipher.

PHP PDO: Do the fetch styles FETCH_CLASS and FETCH_INTO fetch into private object properties?

Very short answer: Yes it will.

class Foo
{
private $id;
public function echoID()
{
echo $this->id;
}
}
$result = $statement->fetchAll(PDO::FETCH_CLASS, "Foo");
$result[0]->echoID(); // your ID

Aside:

This will cause syntax errors $statement->fetchAll(PDO::FETCH_INTO, $User);. You can't use FETCH_INTO with the fetchAll method.

PDO fetch single class not working

I found the answer to the question by myself, i post the answer for everyone.

Instead of using directly PDO::FETCH_CLASS, $Class, i switched using setFetchMode() passing PDO_FETCH_INTO, new $Object instance.

This return correctly new instance of given object (with object methods and fields). Works well with public attributes and overloaded constructors.

The previously statement "findAll() works" wasn't true, i was returning somehow like FETCH_OBJ, an object representation of the database table.

Here the solution:

public function fetchSingleObject($object) {
$this->stm->setFetchMode(PDO::FETCH_INTO, new $object());
$this->execute();
return $this->stm->fetch();
}

Return a new instance of passed in object.

Works also as fetchAll()

EDIT:

public function fetchObjectSet($object) {

$this->execute();
return $this->stm->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, get_class($object));
}


Related Topics



Leave a reply



Submit