Question

I'm hoping you can shed some light to my questions guys. What I need is basically the best practise of getting and assigning properties from database rows (instance getter). It is a pretty standart issue and I have know how it works in C#, but I'm unclear how to accomplish similar results in php and havent found any solution online which covers my needs.

So lets assume I have this simplified code:

Class User{
  private $Pdo;
  private $UserID;
  private $UserName;

  function GetUserName(){
    return $this->UserName;
    }

  function GetUserInfo(){
    // return user object with given user id, in this example just use "1"
    $Pdo = $this->Pdo;
    $Query = $Pdo->query('select * from User where UserID = 1');
    $Query->setFetchMode(PDO::FETCH_CLASS, "User", array($Pdo) ); // this is returning object
    $UserInfo = $Query->fetch();
    return $UserInfo;
    }

  }

Then when I wanted to get the user object I would call it like:

$User = new User($Pdo);
$UserInfo = $User->GetUserInfo();
echo $UserInfo->GetUserName();

This works, however I dont like to do it this way. One option would be to use static method so in the end I would end up with something like:

$UserInfo = User::GetUserInfo()

Which I suppose is called "Singleton" (edit: not a singleton:)) and is generally noted as bad practise.

My question is how it should look like? What I would like to have is this:

$UserInfo = new User($Pdo);
$UserInfo->GetUserInfo();
echo $UserInfo->GetUserName();

I know that in GetUserInfo method I can manually assign the values to current object ($this) such as:

function GetUserInfo(){
    // get data from db
    $this->UserName = "John"; // this value I will get from db
   }

However I would like to use FetchClass so I can get all the properties based on their names in one line and not assign them manually. I hope that you understand what my issue is :) I would love to hear your opinions of what is the best way of doing this.

Thank you very much for any input.

Was it helpful?

Solution

One step in the direction to a best pratice and good design would be to separate your domain models and the persistence layer.

So you are independent of the used database or could even replace the database with a webservice for example. Look at the Data Mapper pattern.

So your User model would only consist of the properties + getters/setters and methods that use these properties in some way (business logic).

class User
{
    protected $UserID;
    protected $UserName;

    public function getUserId()
    {
        return $this->UserID;
    }

    public function setUserId($userId)
    {
        $this->UserID = userId;
        return $this;
    }

    ...

}

Your mapper holds the database connection and is responsible for saving/fetching the User object.

class UserMapper
{
    protected $_pdo;

    public function __construct($pdo)
    {
        $this->_pdo = $pdo;
    }

    public function getUserById($id)
    {
        // TODO: better use prepared statements!
        $query = $this->_pdo->query("select * from User where UserID = ".id);
        $query->setFetchMode(PDO::FETCH_CLASS, "User");
        return $query->fetch();
    }

    public function save(User $user)
    {
        // insert/update query
    }

    ...

}

You can use it like:

$userMapper = new UserMapper($pdo);
$user = $userMapper->getUserById(1);

echo $user->getUserName();

$user->setUserName('Steve');
$userMapper->save($user);

There are other similar patterns like Table Gateway pattern. But I prefer the data mapper because of the independecy of the data source.

Look at the whole catalog from Martin Fowler: Catalog of Patterns of Enterprise Application Architecture

Another useful thread: What is the difference between the Data Mapper, Table Data Gateway (Gateway), Data Access Object (DAO) and Repository patterns?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top