Reputation: 645
i am making a database abstraction class that binds objects like an ORM. I'm having issue with a particular case, fetching a single row and binding to a class. While the same is working well with fetchAll() i can't figure out why using fetch(PDO::FETCH_CLASS) the object returns null. if i use PDO::FETCH_LAZY it works, but isn't a correct binding to the passed class. Here the code. The Database() class is connects to db using PDO. Products() is a class made of public attributes with same name of tables. The controller:
public function editProducts($params) {
$products = new Products();
$db = new Database ();
$id = array_keys($params);
$products = $db->findById($products, $id[0]); // auto Bind object fetched=no and POST params?
$this->template = new Template();
$this->template->renderArgs("product", $products);
$this->template->renderArgs("page_title", "Edit product " . $products->title);
$this->template->render(get_class($this), "editProducts");
}
The DB class:
public function findById($object,$id) {
try {
$table = $this->objectInjector($object);
} catch (Exception $e) {
if (APP_DEBUG) {
d($e->getTrace());
}
return;
}
$statement = "SELECT * FROM $table WHERE id=:id";
$this->stm = $this->pdo->prepare($statement);
$this->bindValue(":id",$id);
return $this->fetchSingleObject($object);
}
the method that abstract fetch:
public function fetchSingleObject($object) {
$this->execute();
$this->stm->setFetchMode(PDO::FETCH_CLASS, get_class($object));
return $this->stm->fetch(PDO::FETCH_CLASS);
//return $this->stm->fetch(PDO::FETCH_LAZY); this works!
}
I missed something? the fetchAll() works nicely in this way:
public function fetchObjectSet($object) {
$this->execute();
$this->stm->setFetchMode(PDO::FETCH_CLASS, get_class($object));
return $this->stm->fetchAll(PDO::FETCH_CLASS);
}
Thank you so much. PS: some methods like $this->execute() are just abastractions to pdo->statment method since pdo and stm are db class instance variables.
Upvotes: 2
Views: 2437
Reputation: 645
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));
}
Upvotes: 4
Reputation: 33813
The manual states:
bool PDOStatement::setFetchMode ( int $PDO::FETCH_CLASS , string $classname , array $ctorargs )
so perhaps try:
$this->stm->setFetchMode(PDO::FETCH_CLASS, 'get_class', $object );/* is $object an array ? */
or, without
$this->stm->setFetchMode(PDO::FETCH_CLASS, 'get_class' );
Upvotes: -1