Table data gateway and DI


I’m reading about different patterns in regards to db data access and manipulation. I’m leaning towards table data gateway but my question is more general about object creation and DI.

Let’s say I have the following controller.

class UserController {

    function __construct(UserGateway $gateway) {
        $this->gateway = $gateway;

    function execute() {
        $user = $this->gateway->find($id);


So on success, find method of UserGateway object should return an instance of User class with data matching the passed $id value.

So after reading all the discussion about not using “new”, what is the best way to return a new instance from within a method?

At first I was thinking about something like

class UserGateway {

    function __construct(DB $pdo, User $user) {
        $this->pdo  = $pdo;
        $this->user = $user;
    function find($id) {
        $query = $this->pdo->query("...", PDO::FETCH_INTO, clone $this->user);
        return $query->fetch();

But it doesn’t feel right and besides, if the User class as a constructor, it won’t be called this way…
The other alternatives are of course calling new User in find() or passing the DI container to the Gateway which would kinda defeat the idea of DI.

I feel like I’m missing something very obvious. I hope somebody helps :slight_smile:


Not using the “new” keyword isn’t the solution DI is meant for. It’s meant to make sure that your application will automagically retrieve dependencies. The user in this case is not a dependency, just a simple object you need to work with. Just use $user = new User; there’s nothing wrong with doing that.

OK, my example was very simplistic - imagine that User has dependencies.
I wonder what would be the solution in such case, as the gateway has no knowledge of those dependencies (unless they are passed in the constructor, but that doesn’t feel right).

Here’s the missing puzzle:

class User {

    function __construct(SomeDependency $dep) {
        $this->dep = $dep;

    function doSomething() {