Programster's Blog

Tutorials focusing on Linux, programming, and open-source

Slim 4 Cheatsheet

Related Posts

Getting Started

Install the framework with:

composer require slim/slim 4.*
composer require slim/psr7

We went with the slim/psr7 implementation of the request and response, but you can use others.

Then get started by putting the following in ./public/index.php

<?php
require_once(__DIR__ . '/../vendor/autoload.php');
$app = Slim\Factory\AppFactory::create();
$app->addErrorMiddleware($displayErrorDetails=true, $logErrors=true, $logErrorDetails=true);

$app->get('/', function (Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response) {
    $body = $response->getBody();
    $body->write('Hello world'); // returns number of bytes written
    $newResponse = $response->withBody($body);
    return $newResponse;
});

$app->run();

run with:

php -S localhost ./public/index.php

Routing

Route Variables

Having a route like /hello?name=john is pretty ugly. It would be much nicer to have a route like /hello/john. You can use something like below to allow a variable name in the route and pass it to a function

$app->get('/hello/{name}', function (Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response, array $args) {
    $name = $args['name'];
    $body = $response->getBody();
    $body->write('Hello world'); // returns number of bytes written
    $newResponse = $response->withBody($body);
    return $newResponse;
});

Body Parameters

To get the body parameters, you need to use:

$request->getParsedBody()

... however, for that to work, you need to ensure the body parsing middleware is run by adding:

$app->addBodyParsingMiddleware();

I have not tested if you do not need to make this addition when using x-www-form-urlencoded fields instead of a JSON string body.

Returning JSON Responses

$responseData = array('hello' => 'world');
$responseBody = json_encode($responseData);
$response->getBody()->write($responseBody);
$newResponse = $response->withHeader('Content-Type', 'application/json');
return $newResponse;

Returning A Redirect

This is easier with just providing you a function:

/**
 * Create a redirect response;
 * @param string $newLocation - where you wish to redirect the user.
 * @param Slim\Psr7\Response $response - the existing response to work with
 * @param bool $useTemporaryRedirect - whether this redirect is temporary, or browser should cache it.
 * @return Slim\Psr7\Response - the redirect response.
 */
function redirect(
    string $newLocation, 
    Slim\Psr7\Response $response, 
    bool $useTemporaryRedirect=true
) : Slim\Psr7\Response
{
    $httpCode = ($useTemporaryRedirect) ? 302 : 301;
    $response = $response->withHeader('Location', $newLocation);
    $response = $response->withStatus($httpCode);
    return $response;
}

Abstract Slim Controller

Whenever I create a new Slim project, I always like creating this class right off the bat which all my "concrete" controllers extend. This way I access the request, response, and args with $this->m_.

<?php


abstract class AbstractSlimController
{
    protected Psr\Http\Message\RequestInterface $m_request;
    protected \Psr\Http\Message\ResponseInterface $m_response;
    protected $m_args;


    public function __construct(\Psr\Http\Message\RequestInterface $request, \Psr\Http\Message\ResponseInterface $response, $args) {
        $this->m_request = $request;
        $this->m_response = $response;
        $this->m_args = $args;
    }


    // this one is optional - refer to Slim3 - Simplifying Routing At Scale
    // https://blog.programster.org/slim3-simplifying-routing-at-scale
    abstract public static function registerRoutes($app);
}

References

Last updated: 6th July 2021
First published: 15th August 2020