Pragmatism in the real world

Route specific configuration in Slim

Note: This article was updated on 14 October 2019 to cover Slim 4 in additional to Slim 3. A friend emailed me recently asking about route specific configuration in Slim. He wants to be able to set properties when creating the route that he can pick up when the route is matched. The way to do this is using route arguments. I've written about route arguments before in the context of setting default values for… continue reading.

Replacing a built-in PHP function when testing a component

Recently I needed to test part of Slim that uses the built-in PHP functions header() and headers_sent(). To do this, I took advantage of PHP's namespace resolution rules where it will find a function within the same namespace first before finding one with the same name in the global namespace. The idea of how to do this came courtesy of Matthew Weier O'Phinney where this approach is used for similar testing in Zend-Diactoros. This is… continue reading.

Default route arguments in Slim

A friend of mine recently asked how to do default route arguments and route specific configuration in Slim, so I thought I'd write up how to do it. Consider a simple Hello route: $app->get("/hello[/{name}]", function ($request, $response, $args) { $name = $request->getAttribute('name'); return $response->write("Hello $name"); }) This will display "Hello " for the URL /hello and "Hello Rob" for the URL /hello/Rob. If we wanted a default of "World", we can set an argument on… continue reading.

Slim's route cache file

When you have a lot of routes, that have parameters, consider using the router's cache file to speed up performance. To do this, you set the routerCacheFile setting to a valid file name. The next time the app is run, then the file is created which contains an associative array with data that means that the router doesn't need to recompile the regular expressions that it uses. For example: $config = [ 'settings' => [… continue reading.

Stand-alone usage of Zend-InputFilter

Any data that you receive needs to be checked and validated. There are number of ways to do this including PHP's filter_var, but I prefer Zend-InputFilter. This is how to use it as a stand-alone component. Installation Firstly, we install it using Composer: $ composer require zendframework/zend-inputfilter $ composer require zendframework/zend-servicemanager You don't have to have ServiceManager, but it makes working with InputFilter much easier, so it's worth installing. Create the InputFilter The easiest way… continue reading.

Rendering problem details in Slim

As I've already noted, in the project I'm currently building, I'm rendering errors in my Slim Framework API using RFC 7807: Problem Details for HTTP APIs via Larry Garfield's ApiProblem component and rka-content-type-renderer. One place where we need to integrate this approach into Slim is in the error handlers. Let's look at NotFound. To ensure that we return a response in the right format, we need to implement our own NotFound handler: src/App/Handler/NotFound.php: <?php namespace… continue reading.

Handling JSON data errors in Slim 3

When you send JSON data into a Slim Framework application with a content-type of application/json, then Slim will decode it for you if you use getParsedBody(): $app->post("/", function ($request, $response, $args) { $input = $request->getParsedBody(); var_dump($input);exit; }); Using curl to test: $ curl -H "Content-Type: application/json" http://localhost:8888 -d '{"foo": "bar"}' array(1) { 'foo' => string(3) "bar" } If there's an error however, you get this: $ curl -H "Content-Type: application/json" http://localhost:8888 -d '{foo: bar}' NULL… continue reading.

Checklist for releasing Slim

Release process for Slim so that I don't forget any steps; based on a check list created by Asgrim. I should probably automate some of this! Preparation: Ensure all merged PRs have been associated to the tag we're about to release.Find them via this search: [is:pr is:closed no:milestone is:merged]. Close the milestone on GitHub. Create a new milestone for the next patch release. Ensure that you have the latest master & that your index is… continue reading.

Filtering the PSR-7 body in middleware

Sometimes, there's a requirement to alter the data in the Response's body after it has been created by your controller action. For example, we may want to ensure that our brand name is consistently capitalised. One way to do this is to create middleware that looks like this: $brandFilter = function ($request, $response, $next) { // call next middleware $response = $next($request, $response); $content = (string)$response->getBody(); $newContent = str_ireplace('nineteen feet', 'Nineteen Feet', $content); $response->getBody()->rewind(); $response->getBody()->write($newContent);… continue reading.

Slim 3.4.0 now provides PSR-7!

I've been neglecting Slim's PR queue recently, so this weekend I dedicated a lot of time to merging all the good work that our contributors have done. As a result, I'm delighted to release version 3.4.0! This release has a larger set of changes in it than I would have ideally liked which is a direct consequence of having gone two months between releases rather than one. One particularly interesting addition that we have a… continue reading.