1

I've been suggested to use Mappers to separate object storage in db from real object behaviour, which sounds like a nice idea. But being used to other OOP languages like Java or SmallTalk, I always try to encapsulate my objects the most I can. I've read several mappers examples and some of them access the variables of the domain object directly (which would be my last choice, though I know it's more comfortable).

The only solution I currently come up with is something like:

class User{
   public __construct($mapped_data){
   foreach($data as $key=>$value){
      $this->$key=$value;
   }
...
}

class UserMapper{
   private populate($user,$db_data){
      ...
      $map=array('id'=>'id','psw'=>'password','mail'=>'email', ...);
      foreach($db_data as $key=>$value){
         $mapped_data[$map[$key]]=$value;
      }
      return new User($mapped_data);
   }
}

The map is because the class User doesn't have to know the db column names at all.

Is this approach correct? Is there a better one? Thanks

Riskz
  • 239
  • 1
  • 11
  • unless you are planning to make the class available for other users, to me this approach is just bloating. the class will not be independent, it will still be dependent on a mapper instead of db names. so the mapper works like a config file. it would be useful if you are planning to make it available to others. IMHO – Dreaded semicolon Jul 23 '11 at 08:45
  • So I should better have a setter and getter for every variable in the class? (or just make them all public). – Riskz Jul 23 '11 at 08:51

1 Answers1

2

I would suggest that Data Access Objects are a more appropriate pattern for what you want to achieve. The Mapper that you show above just increases the complexity but doesn't really provide much in the way of benefits.

In terms of getters and setters, you can use some of PHP's magic methods to clean up the code above. The following allows you to store your data in a protected array while providing access to it that looks like it's just via the object property, but is actually through a method (so that you can provide your own logic there; make things read only, or hide some, etc).

<?php
class User {
protected $_data = array();
public function __construct($data) {
    $this->_data = $data;
}

// Get any value
public function __get($key) {
    return array_key_exists($key, $this->_data) ? $this->_data[$key] : null;
}

// Set any value; leave out to make the data read only outside the class
public function __set($key, $val) {
    $this->_data[$key] = $val;
}

// You should also implement __isset() and __unset()
}

You can then access the data like

<?php
$user = new User(array('foo' => 'bar'));

// Outputs "bar"
echo $user->foo;

You might also simplify this all for yourself by using an existing PHP ORM library.

Community
  • 1
  • 1
El Yobo
  • 14,823
  • 5
  • 60
  • 78
  • I'll take a look at those libraries. Which one would you recommend me? – Riskz Jul 23 '11 at 08:56
  • I haven't worked much with any; I wrote my own, then wished that I'd used one of those instead ;) I did use Doctrine a little when playing around with the Symfony framework, it might be a good place to start. – El Yobo Jul 23 '11 at 09:22
  • Downloading... for what I've read it will make my work easier. Thanks – Riskz Jul 23 '11 at 09:26