I was in the exact same position as you not so long ago so I will answer this on my experience and how I am currently solving this problem.
I have experimented with the implementation you showed above, creating a domain object, setting the values and then passing the object into the fetch method. I found it to be very verbose so I came up with a new way. Basically if you have a Mappers\User
you pass an Entities\User
into it on construction. When the mapper is mapping data to the domain object it simple clones the injected Entities\User
object it holds, sets the data and returns the newly cloned object so I can have the API like this:
public function fetchById($id);
You should look into the repository pattern for dealing with more complicated queries than fetching by an ID. It gives you a wide API for fetching an object or collections of objects in a variety of ways.
So you could have your Repositories\User
with
public function fetchByUsername($username);
public function fetchByEmailAddress($emailAddress);
How you implement the internals of the repository is up to you there are many different takes on it like with most programming patterns. Your Repositories\User
could hold your Mappers\User
so when you fetch the user by the username for example you just use the mapper within the repository to map the data and return the user. All this is encapsulated by the repositories public interface.