Skip to main content

Having fun with PSR-7

This blog post might be outdated!
This blog post was published more than one year ago and might be outdated!
· 2 min read
Stephan Hochdörfer
Head of IT Business Operations

When I came up with the idea to build a PSR-7 based flat-file CMS I thought that it must be fairly trivial to build a static page exporter by simply "faking" requests and storing the resulting responses. Turns out I was right and this an quick recap of what I did ;)

To build the application I make use of our PSR-7 micro-framework called Adrenaline which in turn is using our ADR / PSR-7 based middleware called Adroit. Adrenaline and Adroit use Diactoros, the PSR-7 HTTP Message implementation by Zend.

In Diactoros emitters are responsible for processing responses, e.g. by sending them back to the client. The general idea was that I simply needed to implement an emitter class that would write the response to the file. Passing a custom emitter instance to Adrenaline is easy, just pass the emitter instance as 4th constructor parameter:

$emitter = ...
$router = new \bitExpert\Pathfinder\Psr7Router();
$app = new \bitExpert\Adrenaline\Adrenaline([], [], $router, $emitter);
$app();

The emitter gets triggered in the __invoke() method of Adrenaline after all middlewares have been executed. All that is left is to fire requests against the app and let the emitter do the hard work:

$request = \Zend\Diactoros\ServerRequestFactory::fromGlobals();
$response = new Zend\Diactoros\Response();

$request = $request->withUri(new Uri('/my-page'));
$app($request, $response);

There is one more problem to solve: The emitter only gets passed the response object and thus the emitter does not know what the current requests looks like. This means I needed to find another way to pass the information about the "name" of the current page to the emitter. I need this information in the emitter to be able to know how the file needs to be called and in which folder it needs to placed. I could have initialized the emitter with the name of the page before "firing" the request but that felt wrong. I went a different route: In my responder class I simply set a custom response header like "X-Pagename" and in the emitter access the header variable.

$headers = $response->getHeader('X-Pagename');
if (count($headers) === 0) {
return;
}

$pageName = $headers[0] ?: '';

As you can see PSR-7 is pretty powerful when used correctly ;)