Slim is a micro framework for PHP

Slim is a micro framework for PHP . We can build quickly powerful web applications and APIs. Slim is a dispatcher that receives an HTTP request, invokes an appropriate callback routine, and returns an HTTP response.

Slim is an ideal tool to create APIs that consume, repurpose, or publish data. Slim is also a great tool for rapid prototyping. Heck, we can even build full-featured web applications with user interfaces. More importantly, Slim is super fast and has very little code. In fact, we can read and understand its source code in only an afternoon!

 

First, we need a web server like Apache. We should configure our web server  so that it sends all appropriate requests to one “front-controller” PHP file. We instantiate and run our Slim app in this PHP file.

A Slim app contains routes that respond to specific HTTP requests. Each route invokes a callback and returns an HTTP response. To get started, we first instantiate and configure the Slim application. Next, we define our application routes. Finally, we run the Slim application. It’s that easy. Here’s an example application:

<?php
// Create and configure Slim app
$config = ['settings' => [
    'addContentLengthHeader' => false,
]];
$app = new \Slim\App($config);

// Define app routes
$app->get('/hello/{name}', function ($request, $response, $args) {
    return $response->write("Hello " . $args['name']);
});

// Run app
$app->run();

When we build a Slim app, we are often working directly with Request and Response objects. These objects represent the actual HTTP request received by the web server and the eventual HTTP response returned to the client.

Every Slim app route is given the current Request and Response objects as arguments to its callback routine. These objects implement the popular PSR7  interfaces. The Slim app route can inspect or manipulate these objects as necessary. Ultimately, each Slim app route must return a PSR7  Response object.

Slim is designed to play well with other PHP components, too. We can register additional first-party components  that build upon Slim’s default functionality. It’s also easy to integrate third-party components found on Packagist.

If anyone is new to Slim, I recommend to read this documentation from start to finish. If anyone is already familiar with Slim, she/he can instead jump straight to the appropriate section.

This documentation begins by explaining Slim’s concepts and architecture before venturing into specific topics like request and response handling, routing, and error handling.

Installing slim:
We recommend to install Slim with Composer. Navigate into project’s root directory 
and execute the bash command shown below. This command downloads the Slim Framework and its 
third-party dependencies into your project’s vendor/ directory. 
composer require slim/slim "^3.0"
Require the Composer autoloader into your PHP script, and you are ready to start using Slim.
<?php
require 'vendor/autoload.php';

Don’t have Composer? It’s easy to install by following the instructions on their download page.
If one is upgrading from version 2 to version 3, these are the significant changes that need to be aware of.
Slim 3 requires PHP 5.5 or latest version.

New Route Function Signature
$app->get('/', function (Request $req,  Response $res, $args = []) {
    return $res->withStatus(400)->write('Bad Request');
});

Getting _GET and __POST variables
$app->get('/', function (Request $req,  Response $res, $args = []) {
    $myvar1 = $req->getParam('myvar'); //checks both _GET and _POST [NOT PSR-7 Compliant]
    $myvar2 = $req->getParsedBody()['myvar']; //checks _POST  [IS PSR-7 compliant]
    $myvar3 = $req->getQueryParams()['myvar']; //checks _GET [IS PSR-7 compliant]
});
Hooks are no longer part of Slim as of v3. You should consider reimplementing any functionality associated with the default hooks in Slim v2 as middleware instead.
If you need the ability to apply custom hooks at arbitrary points in your code (for example, within a route), you should consider a third-party package 
such as Symfony’s EventDispatcher or Zend Framework’s EventManager.

Remova;l HTTP Cache

In Slim v3 we have removed the HTTP-Caching into its own module Slim\Http\Cache.

Removal of Stop/Halt

Slim Core has removed Stop/Halt. In your applications, you should transition to using the withStatus() and withBody() methods.

Removal of autoloader

Slim::registerAutoloader() have been removed, we have fully moved to composer.

Changes to container

$app->container->singleton(...) is now $app['...'] = function () {}; Please read Pimple docs for more info

Removal of configureModel()

$app->configureMode(...) has been removed in v3.

 

Removal of PrettyExceptions

PrettyExceptions cause lots of issues for many people, so this have been removed.

ROute::setDefaultConditions(…) has been removed

We have switched routers which enable you to keep the default conditions regex inside of the route pattern.

Changes to redirect

In Slim v2.x one would use the helper function $app->redirect(); to trigger a redirect request. In Slim v3.x one can do the same with using the Response class like so.

Example:

$app->get('/', function ($req, $res, $args) {
  return $res->withStatus(302)->withHeader('Location', 'your-new-uri');
});

Middleware Signa

The middleware signature has changed from a class to a function.

New signature:

use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;

$app->add(function (Request $req,  Response $res, callable $next) {
    // Do stuff before passing along
    $newResponse = $next($req, $res);
    // Do stuff after route is rendered
    return $newResponse; // continue
});

You can still use a class:

namespace My;

use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;

class Middleware
{
    function __invoke(Request $req,  Response $res, callable $next) {
        // Do stuff before passing along
        $newResponse = $next($req, $res);
        // Do stuff after route is rendered
        return $newResponse; // continue
    }
}


// Register
$app->add(new My\Middleware());
// or
$app->add(My\Middleware::class);

Middleware Execution

Application middleware is executed as Last In First Executed (LIFE).

Flash Message

Flash messages are no longer a part of the Slim v3 core but instead have been moved to seperate Slim Flash package.


In v3.0 cookies has been removed from core. See FIG Cookies for a PSR-7 compatible cookie component.

Removal of Crypto

In v3.0 we have removed the dependency for crypto in core.

New Router

Slim now utilizes FastRoute, a new, more powerful router!

This means that the specification of route patterns has changed with named parameters now in braces and square brackets used for optional segments:

// named parameter:
$app->get('/hello/{name}', /*...*/);

// optional segment:
$app->get('/news[/{year}]', /*...*/);

Route Middleware

The syntax for adding route middleware has changed slightly. In v3.0:

$app->get()->add($mw2)->add($mw1);

Getting the current route

The route is an attribute of the Request object in v3.0:

$request->getAttribute('route');

When getting the current route in middleware, the value for determineRouteBeforeAppMiddleware must be set to true in the Application configuration, otherwise the getAttribute call returns null.

urlFor() is now pathFor in the router

urlFor() has been renamed pathFor() and can be found in the router object:

$app->get('/', function ($request, $response, $args) {
    $url = $this->router->pathFor('home');
    $response->write("<a href='$url'>Home</a>");
    return $response;
})->setName('home');

Also, pathFor() is base path aware.

Container and DI  ….. Constractiing

Slim uses Pimple as a Dependency Injection Container.

// index.php
$app = new Slim\App(
    new \Slim\Container(
        include '../config/container.config.php'
    )
);

// Slim will grab the Home class from the container defined below and execute its index method.
// If the class is not defined in the container Slim will still contruct it and pass the container as the first arugment to the constructor!
$app->get('/', Home::class . ':index');


// In container.config.php
// We are using the SlimTwig here
return [
    'settings' => [
        'viewTemplatesDirectory' => '../templates',
    ],
    'twig' => [
        'title' => '',
        'description' => '',
        'author' => ''
    ],
    'view' => function ($c) {
        $view = new Twig(
            $c['settings']['viewTemplatesDirectory'],
            [
                'cache' => false // '../cache'
            ]
        );

        // Instantiate and add Slim specific extension
        $view->addExtension(
            new TwigExtension(
                $c['router'],
                $c['request']->getUri()
            )
        );

        foreach ($c['twig'] as $name => $value) {
            $view->getEnvironment()->addGlobal($name, $value);
        }

        return $view;
    },
    Home::class => function ($c) {
        return new Home($c['view']);
    }
];

PSR7-7 objects

Request, Response, Uri & UploadFile are immutable.

This means that when you change one of these objects, the old instance is not updated.

// This is WRONG. The change will not pass through.
$app->add(function (Request $request, Response $response, $next) {
    $request->withAttribute('abc', 'def');
    return $next($request, $response);
});

// This is correct.
$app->add(function (Request $request, Response $response, $next) {
    $request = $request->withAttribute('abc', 'def');
    return $next($request, $response);
});

Message bodies are streams

// ...
$image = __DIR__ . '/huge_photo.jpg';
$body = new Stream($image);
$response = (new Response())
     ->withStatus(200, 'OK')
     ->withHeader('Content-Type', 'image/jpeg')
     ->withHeader('Content-Length', filesize($image))
     ->withBody($body);
// ...

For text:

// ...
$response = (new Response())->getBody()->write('Hello world!')

// Or Slim specific: Not PSR-7 compliant.
$response = (new Response())->write('Hello world!');


The end