I implemented a little IdentityMap into my DataMappers and it works correctly in the way that it knows if an object has already been loaded but it does not assign the in memory object properly.
I have simplified the code down as much as I can (it's not complicated anyway) to one entity, no database etc. Could someone please explain why in the lookup() method does not properly assign the already loaded Customer object to the passed in Customer object?
Customer.php
class Customer {
private $id;
private $name;
public function getId() {
return $this->id;
}
public function setId($id) {
$this->id = $id;
}
public function getName() {
return $this->name;
}
public function setName($name) {
$this->name = $name;
}
}
CustomerMapper
class CustomerMapper {
private $identityMap;
public function __construct(IdentityMap $identityMap) {
$this->identityMap = $identityMap;
}
public function fetch(Customer $customer) {
if( $this->identityMap->lookup($customer) ) {
return true;
}
$this->assign($customer, array('id' => 1, 'name' => 'John'));
}
private function assign(Customer $customer, Array $row) {
$customer->setId($row['id']);
$customer->setName($row['name']);
$this->identityMap->add($customer);
}
}
IdentityMap
class IdentityMap {
private $customers;
public function lookup(Customer $customer) {
if( !array_key_exists($customer->getId(), $this->customers) ) {
return false;
}
$customer = $this->customers[$customer->getId()]; //Something wrong here?
return true;
}
public function add(Customer $customer) {
$this->customers[$customer->getId()] = $customer;
}
}
When I then run this:
$identityMap = new IdentityMap();
$customerMapper = new CustomerMapper($identityMap);
for( $i = 0; $i < 3; $i++ ){
$customer = new Customer();
$customer->setId(1);
$customerMapper->fetch($customer);
echo 'ID: ' . $customer->getId() . '<br>Name: ' . $customer->getName() . '<br><br>';
}
Output:
ID: 1
Name: John
ID: 1
Name:
ID: 1
Name:
Why do the second and third Customer objects have no name? I am fairly sure there is a problem in the assigning part in the lookup() method. I have been at this since last night trying and reading everything.
I have changed the lookup() methods signature to having the "&" symbol in front of the passed in object with no luck.
public function lookup(Customer &$customer)so that it's passed by reference and not by value.