kevin hendrickx
kevin hendrickx

Reputation: 116

Dependency injection php website

The more I read about dependency injection the more I get confused. I know what it is for, that is not the problem. Trying to do some design on paper this is what I came up with and somehow it seems to me I am overlooking something.

First I imagined building an actual server that would accept incoming requests and returns responses to the user.

class Server {
  private $responseBuilder;

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

  public function run() {
    // create socket, receive request
    $response = $this->responsebuilder->build($request);
    // send response
  }
}

class Response {
  private $method;
  private $message;
  private $url;

  // getters & setters
}

class ServerBuilder {
   public build() {
      // construction logic
      return new Server(new ResponseBuilder());
   }
}

Since Apache is used to handle server requests we could replace the server with something that just send the response.

$bldr = new ResponseBuilder();
$response = $bldr->build();
// send response some way

Note that ResponseBuilder has direct access to the request ($_SERVER['..']) and so it has everything it needs to choose the right response.

PHP however allows us to build and send responses inline. So we could have a Controller object for each page or something else that send the response and have a builder for that.

$bldr = new ControllerBuilder();  
$controller = $bldr->build();
$controller->run();

class ExampleController implements Controller {
    public function run() {
       header("HTTP/1.1 404 Not Found");
       echo 'sorry, page not found';
    }
} 

This all makes sense to me. But let's look at the server example again. It calls $responseBuilder->build() and gets a response back. But this would mean that the builder (or other builders if we split it) is also responsible for anything else that might occur like authenticating a user, writing to the database,... and I can't get my head around the fact that writing to a database would be part of the object graph construction. It would be like: Send me your request. Oh you want the homepage? I will build you your response and while I'm at it I will also do some things that have nothing to do with building it like logging what I just did and saving some of your data in a cookie and sending a mail to the administrator that you are the first visitor on this page ever, ...

Upvotes: 2

Views: 162

Answers (1)

David
David

Reputation: 1246

You should decouple them. You have a few assumptions that I think are a bit strange. Let's start with them.

The main purpose of an incoming http request is to give back some html

I have built PHP backends that only return JSON, instead of HTML. I had a really strong border between back and front end. I only used the backend to give me data from the database, or add/edit data in the databse. The front end was just a PHP script that would build the pages any way i wanted.

Since it is the web there is in theory no use for setters since everything can be injected in the constructor

You could use the constructor, but you don't have too. You can use setters. Dependency injection is actually just turning the flow around.

You are on the right track though. You want some class that is responsible for building your pages. So, make it only responsible for your building your pages, and take out the other responsibilities. Things like logging, authentication etc should be outside of that.

For instance if you want logging, you could have your builder create your page, and your logger could then listen to all the things your builder is doing (with the observer pattern for instance). So if your builder says: "i created the home page", you can log it with your logger, who is actually listening to your builder.

Authentication for instance should happen even before your builder starts. You don't want your builder to go to work if you can already figure out that a user is not supposed to be on a page. You could use a database for that, and whitelist any usertype/pagerequest combination.

Then for data handling, i would create a backend, that only handles requests that are supposed to give back data, or save it. The front end could then communicate to get it's content by pulling it.

I hope this clears up a few things, but I'll be happy to answer more indept questions.

Upvotes: 1

Related Questions