The Slim 3 Introduction

Getting to know Slim 3.x

For those uninitiated Slim is an unopinionated php micro-framework. Slim lets you do things how you want, and does not force you into structures or patterns.
In this blog post we are going to cover the basics and get you up and running quickly with Slim

Let's take a look at a "Hello world" App

//It's recommended that you install it via composer
//composer require slim/slim "^3.0@RC"

require 'vendor/autoload.php';

$app = new Slim\App();

ServerRequestInterface - $request
ResponseInterface - $response
Array - $args

$app->get('/hello', function ($request, $response, $args) {
    $response->write("Hello World");
    return $response;


At it's core Slim is a middleware runner. You will need to get used to the $request, $response, $args pattern.
Acccessing the /hello url will return what you expect.

Slim 3 is fully PSR-7 compliant [Read about it here]. Minimally this means it takes a browser "Request", applies middleware, and returns a "Response".


Almost all instances of the Request refer to a ServerRequest. This is what Slim constructs from your web server and the rest of the environment. It includes all header information. There is one gotcha though, be careful when you are using Apache, it strips out the Authorization Header. See this issue


This object holds the data you want to send to the browser and it includes HTTP Headers [Cookie or Session], Status Code [200 Right?], body [Your Content ;)].

What about Dependencies?

Slim 3 by default uses the Pimple Dependency Injection Container [DiC]. Those switching from Slim 2 please pay attention to this section.
Slim 3 does not work like Slim 2
In Slim 2, you can pass around the "Slim" class like hot potatoes [Resource Locator]. In Slim 3 this is not the way we want to do things.
The preferred way to do things is via proper Dependency Injection, this is why we have Pimple and a DiC.

First off, Slim 3 knows that migrating is going to be a royal PAIN. Anything that is not created in the DiC Slim 3 happily passes the DiC to the class.
So, fear not friends, you wont spend 100s of hours rewiring it all.

Lets take a look at DI in Slim 3

//Lets Grab the Container
$container = $app->getContainer();

//This replaces the $app->singleton() in Slim v2
$container['MyController'] = function ($c) {
    //This is constructor injection
    return new Controller($c['MyOtherDependency']);

//Example Controller
$app->get('/hi', function ($req, $res, $args) {
    return $this->MyController->myAction($req, $res, $args);

So let's talk about this magic. How does $this get the dependency, and what the heck is "this".

Believe it or not, "this" is actually the App class. $app->get() bind's the App class to the function.
The app class direct's all not-defined items to the container via PHP's magic methods, which is how your dependency is found!


Middleware are pieces of code that you want to run before your route or after it. Typical middlewares are things like authentication or session libraries.
There are 2 different types of Middleware, application wide and route specific. Both have the exact same functionality and the only difference is where and when it gets applied.
Application wide middleware are applied to all routes in your application and as you expect the route specific ones are applied to a route or route group.

So let's take a look at those.

$middleware = function ($req, $res, $next) {
    //Do Something before we execute logic
    $response =  $next($req, $res);
    //Do something after we run our logic, maybe logging?
    return $response;

//Apply it Site Wide

//Apply it per route
$app->get('/hi', function ($req, $res, $args) {
    return $this->MyController->myAction($req, $res, $args);

Route Parameters

The syntax for routing parameters has changed from Slim 2 to 3. Be wary of older articles!




Route arguments are now merged into the $args variable of the Route Callable, with the index of your parameter.

$app->get('/{id}/', function ($req, $res, $args) {
    $id = $args['id']; // Here is your Argument


The Router changed to Nikic's Fast-Router and has a ton of different options. Read about it here


A lot of new comers to PSR-7 have a difficult time with how to access Query Parameters and POST data. Its actually quite easy, but not very straight forward.


$my_get = $request->getQueryParams();


$my_post = $request->getParsedBody();

Happy Coding!

Written by Glenn Eggleton on Tuesday January 26, 2016
Permalink - Chapter: Slim