In my last post you saw me gushing over the new pattern possibilities that attributes open up among ORMs both without tight coupling as well as ActiveRecord style implementations like mine. In this post I want to talk about the move to PSR7 controllers and how that makes it possible to make an emitter that is completely framework agnostic, while also making it possible to write cleaner unit tests.
In 2015, the PHP Framework Interop Group, or FIG for short, introduced PSR7. FIG came together in the first place to define a standard way of doing certain things in PHP. The very first thing they tackled was PSR-0 which defined a standard way of loading code. Before this every PHP project was manually loading it's code. Of course developers wouldn't always pick the exact same way of doing this. PSR-0 standardized code auto loading and was later refined in PSR-4 for namespaces. All this work made composer possible. Suddenly all your code was portable between projects and you didn't really have to worry about naming something the same as another project.
PSR7 extends this concept to the way controllers are written which when followed to it's logical conclusion allows you the ability top migrate controllers between between frameworks.
Request, Response, Emit
PSR7 defines several new interfaces that aren't built into PHP by default. These interfaces provide a standard way of accessing information about the HTTP Request that launched the PHP process but also a standard way of providing a response. The standard itself won't really help you much unless you're knowledgable enough to fully implement it yourself and that is quite the tall order even for someone who is extremely knowledgable. Luckily we can use Guzzle's excellent implementation.
To illustrate how this works let's step back for a second and think about the entire system. How do our processes start? Well assuming you have an nginx to php-fpm system nginx will receive the request then pass it on to php-fpm which will then start a php process. All the details about the request are passed into the process through globals like $_REQUEST, $_GET, $_POST, $_COOKIE, etc. Now let's imagine that we took this data and took a snapshot of it. That is what we get from the Guzzle code linked above. In the class you'll find the method fromGlobals
which creates an immutable ServerRequest object. The comment above the method is succinct in it's description.
/**
* Return a ServerRequest populated with superglobals:
* $_GET
* $_POST
* $_COOKIE
* $_FILES
* $_SERVER
*/
public static function fromGlobals(): ServerRequestInterface