原文出处：http://www.slimframework.com/docs/

Documentation

Welcome

Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs. At its core, Slim is a dispatcher that receives an HTTP request, invokes an appropriate callback routine, and returns an HTTP response. That’s it.

What’s the point?

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

At its core, Slim is a dispatcher that receives an HTTP request, invokes an appropriate callback routine, and returns an HTTP response. That’s it.

You don’t always need a kitchen-sink solution like Symfony or Laravel. These are great tools, for sure. But they are often overkill. Instead, Slim provides only a minimal set of tools that do what you need and nothing else.

How does it work?

First, you need a web server like Nginx or Apache. You should configure your web serverso that it sends all appropriate requests to one “front-controller” PHP file. You instantiate and run your 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, you first instantiate and configure the Slim application. Next, you define your application routes. Finally, you run the Slim application. It’s that easy. Here’s an example application:

      <?php
// Create and configure Slim app
$app = new \Slim\App;

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

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

Figure 1: Example Slim application

Request and response

When you build a Slim app, you 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 PSR 7 interfaces. The Slim app route can inspect or manipulate these objects as necessary. Ultimately, each Slim app route MUST return a PSR 7 Response object.

Bring your own components

Slim is designed to play well with other PHP components, too. You can register additional first-party components such as Slim-Csrf, Slim-HttpCache, or Slim-Flash that build upon Slim’s default functionality. It’s also easy to integrate third-party components found onPackagist.

How to read this documentation

If you are new to Slim, I recommend you read this documentation from start to finish. If you are already familiar with Slim, you 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.

Installation

System Requirements

Web server with URL rewriting

PHP 5.5 or newer

How to Install Slim

We recommend you install Slim with Composer. Navigate into your 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@RC"

Require the Composer autoloader into your PHP script, and you are ready to start using Slim.

      <?php
require 'vendor/autoload.php';

How to Install Composer

Don’t have Composer? It’s easy to install. The following bash command downloads Composer and moves it into your /usr/local/bin directory.

      curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

Upgrade Guide

If you are upgrading from version 2 to version 3, these are the significant changes that you need to be aware of.

Removal of Stop/Halt

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

Example In Slim 2.x:

      $app->get('/', function () {  $app->halt(400, 'Bad Request'); });

And now in Slim 3.x:

      $app->get('/', function ($req, $res, $args) {
    return $res->withStatus(400)->write('Bad Request');
});

Hooks

Slim v3 no longer has the concept of hooks. Hooks were removed as they duplicate the functionality already present in middlewares. You should be able to easily convert your Hook code into Middleware code.

Removal HTTP Cache

In Slim v3 we have removed the HTTP-Caching into its own module Slim\Http\Cache ( https://github.com/slimphp/Slim-HttpCache )

Changed 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(301)->withHeader("Location", "yournewuri");
});

Middleware

Signature —- The middleware signature has changed from a class to a function New signature:

      $app->add(function ($req, $res, $next) {});

Execution

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

Flash Messages

In v3.0 the concept of flash messages has been removed. There currently is no planned feature for this, but could likely be a part of the Cookies package.

Cookies

In v3.0 cookies has been removed from core and moved to a separate component. See (https://github.com/slimphp/Slim-Http-Cookies)

Removal of Crypto

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

PHP Version

Slim v3.0 requires PHP 5.5+

Route Callbacks

In v3.0 we have adopted a new callback signature:

      $app->get('/', function (
    \Psr\Http\Message\ServerRequestInterface $request,
    \Psr\Http\Message\ResponseInterface $response,
    array $args = null) {

    //do stuff!
});

New Router

Slim now utilizes a new, more powerful router ( https://github.com/nikic/FastRoute )!

Route Middleware

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

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

urlFor() is now pathfor() in the router

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

      $router = $app->router;

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

Also, pathFor() is base path aware.

Web Servers

It is typical to use the front-controller pattern to funnel appropriate HTTP requests received by your web server to a single PHP file. The instructions below explain how to tell your web server to send HTTP requests to your PHP front-controller file.

Apache configuration

Ensure your .htaccess and index.php files are in the same public-accessible directory. The.htaccess file should contain this code:

      RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]

Make sure your Apache virtual host is configured with the AllowOverride option so that the.htaccess rewrite rules can be used:

      AllowOverride All

Nginx configuration

This is an example Nginx virtual host configuration for the domain example.com. It listens for inbound HTTP connections on port 80. It assumes a PHP-FPM server is running on port 9000. You should update the server_name, error_log, access_log, and root directives with your own values. The root directive is the path to your application’s public document root directory; your Slim app’s index.php front-controller file should be in this directory.

      server {
    listen 80;
    server_name example.com;
    index index.php;
    error_log /path/to/example.error.log;
    access_log /path/to/example.access.log;
    root /path/to/public;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_index index.php;
        fastcgi_pass 127.0.0.1:9000;
    }
}

HipHop Virtual Machine

Your HipHop Virtual Machine configuration file should contain this code (along with other settings you may need). Be sure you change the SourceRoot setting to point to your Slim app’s document root directory.

      Server {
    SourceRoot = /path/to/public/directory
}

ServerVariables {
    SCRIPT_NAME = /index.php
}

VirtualHost {
    * {
        Pattern = .*
        RewriteRules {
                * {
                        pattern = ^(.*)$
                        to = index.php/$1
                        qsa = true
                }
        }
    }
}

IIS

Ensure the Web.config and index.php files are in the same public-accessible directory. TheWeb.config file should contain this code:

      <?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="slim" patternSyntax="Wildcard">
                    <match url="*" />
                    <conditions>
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="index.php" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

lighttpd

Your lighttpd configuration file should contain this code (along with other settings you may need). This code requires lighttpd >= 1.4.24.

      url.rewrite-if-not-file = ("(.*)" => "/index.php/$0")

This assumes that Slim’s index.php is in the root folder of your project (www root).

PSR 7 and Value Objects

Slim supports PSR-7 interfaces for its Request and Response objects. This makes Slim flexible because it can use any PSR-7 implementation. For example, a Slim application route does not have to return an instance of \Slim\Http\Response. It could, for example, return an instance of \GuzzleHttp\Psr7\CachingStream or any instance returned by the\GuzzleHttp\Psr7\stream_for() function.

Slim provides its own PSR-7 implementation so that it works out of the box. However, you are free to replace Slim’s default PSR 7 objects with a third-party implementation. Just override the application container’s request and response services so they return an instance of\Psr\Http\Message\ServerRequestInterface and\Psr\Http\Message\ResponseInterface, respectively.

Value objects

Slim’s Request and Response objects are immutable value objects. They can be “changed” only by requesting a cloned version that has updated property values. Value objects have a nominal overhead because they must be cloned when their properties are updated. This overhead does not affect performance in any meaningful way.

You can request a copy of a value object by invoking any of its PSR 7 interface methods (these methods typically have a with prefix). For example, a PSR 7 Response object has awithHeader($name, $value) method that returns a cloned value object with the new HTTP header.

      <?php
$app = new \Slim\App;
$app->get('/foo', function ($req, $res, $args) {
    return $res->withHeader(
        'Content-Type',
        'application/json'
    );
});
$app->run();

The PSR 7 interface provides these methods to transform Request and Response objects:

withProtocolVersion($version)

withHeader($name, $value)

withAddedHeader($name, $value)

withoutHeader($name)

withBody(StreamInterface $body)

The PSR 7 interface provides these methods to transform Request objects:

withMethod($method)

withUri(UriInterface $uri, $preserveHost = false)

withCookieParams(array $cookies)

withQueryParams(array $query)

withUploadedFiles(array $uploadedFiles)

withParsedBody($data)

withAttribute($name, $value)

withoutAttribute($name)

The PSR 7 interface provides these methods to transform Response objects:

withStatus($code, $reasonPhrase = '')

Refer to the PSR-7 documentation for more information about these methods.

Middleware

You can run code before and after your Slim application to manipulate the Request and Response objects as you see fit. This is called middleware. Why would you want to do this? Perhaps you want to protect your app from cross-site request forgery. Maybe you want to authenticate requests before your app runs. Middleware is perfect for these scenarios.

What is middleware?

Technically speaking, a middleware is a callable that accepts three arguments:

\Psr\Http\Message\ServerRequestInterface - The PSR7 request object

\Psr\Http\Message\ResponseInterface - The PSR7 response object

callable - The next middleware callable

It can do whatever is appropriate with these objects. The only hard requirement is that a middleware MUST return an instance of \Psr\Http\Message\ResponseInterface. Each middleware SHOULD invoke the next middleware and pass it Request and Response objects as arguments.

How does middleware work?

Different frameworks use middleware differently. Slim adds middleware as concentric layers surrounding your core application. Each new middleware layer surrounds any existing middleware layers. The concentric structure expands outwardly as additional middleware layers are added.

When you run the Slim application, the Request and Response objects traverse the middleware structure from the outside in. They first enter the outer-most middleware, then the next outer-most middleware, (and so on), until they ultimately arrive at the Slim application itself. After the Slim application dispatches the appropriate route, the resultant Response object exits the Slim application and traverses the middleware structure from the inside out. Ultimately, a final Response object exits the outer-most middleware, is serialized into a raw HTTP response, and is returned to the HTTP client. Here’s a diagram that illustrates the middleware process flow:

How do I write middleware?

Middleware is a callable that accepts three arguments: a Request object, a Response object, and the next middleware. Each middleware MUST return an instance of\Psr\Http\Message\ResponseInterface.

Closure middleware example.

This example middleware is a Closure.

      <?php
/**
 * Example middleware closure
 *
 * @param  \Psr\Http\Message\ServerRequestInterface $request  PSR7 request
 * @param  \Psr\Http\Message\ResponseInterface      $response PSR7 response
 * @param  callable                                 $next     Next middleware
 *
 * @return \Psr\Http\Message\ResponseInterface
 */
function ($request, $response, $next) {
    $response->getBody()->write('BEFORE');
    $response = $next($request, $response);
    $response->getBody()->write('AFTER');

    return $response;
};

Invokable class middleware example

This example middleware is an invokable class that implements the magic __invoke()method.

      <?php
class ExampleMiddleware
{
    /**
     * Example middleware invokable class
     *
     * @param  \Psr\Http\Message\ServerRequestInterface $request  PSR7 request
     * @param  \Psr\Http\Message\ResponseInterface      $response PSR7 response
     * @param  callable                                 $next     Next middleware
     *
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function __invoke($request, $response, $next)
    {
        $response->getBody()->write('BEFORE');
        $response = $next($request, $response);
        $response->getBody()->write('AFTER');

        return $response;
    }
}

To use this class as a middleware, you can use ->add( new ExampleMiddleware() );function chain after the $app, Route, or group(), which in the code below, any one of these, could represent $subject.

      $subject->add( new ExampleMiddleware() );

How do I add middleware?

You may add middleware to a Slim application, to an individual Slim application route or to a route group. All scenarios accept the same middleware and implement the same middleware interface.

Application middleware

Application middleware is invoked for every incoming HTTP request. Add application middleware with the Slim application instance’s add() method. This example adds the Closure middleware example above:

      <?php
$app = new \Slim\App();

$app->add(function ($request, $response, $next) {
    $response->getBody()->write('BEFORE');
    $response = $next($request, $response);
    $response->getBody()->write('AFTER');

    return $response;
});

$app->get('/', function ($req, $res, $args) {
    echo ' Hello ';
});

$app->run();

This would output this HTTP response body:

      BEFORE Hello AFTER

Route middleware

Route middleware is invoked only if its route matches the current HTTP request method and URI. Route middleware is specified immediately after you invoke any of the Slim application’s routing methods (e.g., get() or post()). Each routing method returns an instance of\Slim\Route, and this class provides the same middleware interface as the Slim application instance. Add middleware to a Route with the Route instance’s add() method. This example adds the Closure middleware example above:

      <?php
$app = new \Slim\App();

$mw = function ($request, $response, $next) {
    $response->getBody()->write('BEFORE');
    $response = $next($request, $response);
    $response->getBody()->write('AFTER');

    return $response;
};

$app->get('/', function ($req, $res, $args) {
    echo ' Hello ';
})->add($mw);

$app->run();

This would output this HTTP response body:

      BEFORE Hello AFTER

Group Middleware

In addition to the overall application, and standard routes being able to accept middleware, thegroup() multi-route definition functionality, also allows individual routes internally. Route group middleware is invoked only if its route matches one of the defined HTTP request methods and URIs from the group. To add middleware within the callback, and entire-group middleware to be set by chaining add() after the group() method.

Sample Application, making use of callback middleware on a group of url-handlers

      <?php

require_once __DIR__.'/vendor/autoload.php';

$app = new \Slim\App();

$app->get('/', function ($request, $response) {
    return $response->getBody()->write('Hello World');
});

$app->group('/utils', function () use ($app) {
    $app->get('/date', function ($request, $response) {
        return $response->getBody()->write(date('Y-m-d H:i:s'));
    });
    $app->get('/time', function ($request, $response) {
        return $response->getBody()->write(time());
    });
})->add(function ($request, $response, $next) {
    $response->getBody()->write('It is now ');
    $response = $next($request, $response);
    $response->getBody()->write('. Enjoy!');

    return $response;
});

When calling the /utils/date method, this would output a string similar to the below

      It is now 2015-07-06 03:11:01\. Enjoy!

visiting /utils/time would output a string similar to the below

      It is now 1436148762\. Enjoy!

but visiting / (domain-root), would be expected to generate the following output as no middleware has been assigned

      Hello World

Dependency Container

Slim uses a dependency container to prepare, manage, and inject application dependencies. Slim supports containers that implement the Container-Interop interface. You can use Slim’s built-in container (based on Pimple) or third-party containers like Acclimate or PHP-DI.

How to use the container

You don’t have to provide a dependency container. If you do, however, you must inject the container instance into the Slim application’s constructor.

      $container = new \Slim\Container;
$app = new \Slim\App($container);

You can fetch services from your container explicitly or implicitly. You can fetch an explicit reference to the container instance from inside a Slim application route like this:

      /**
 * Example GET route
 *
 * @param  \Psr\Http\Message\ServerRequestInterface $req  PSR7 request
 * @param  \Psr\Http\Message\ResponseInterface      $res  PSR7 response
 * @param  array                                    $args Route parameters
 *
 * @return \Psr\Http\Message\ResponseInterface
 */
$app->get('/foo', function ($req, $res, $args) {
    $container = $this->getContainer();
    $myService = $container->get('myService');

    return $res;
});

You can implicitly fetch services from the container like this:

      /**
 * Example GET route
 *
 * @param  \Psr\Http\Message\ServerRequestInterface $req  PSR7 request
 * @param  \Psr\Http\Message\ResponseInterface      $res  PSR7 response
 * @param  array                                    $args Route parameters
 *
 * @return \Psr\Http\Message\ResponseInterface
 */
$app->get('/foo', function ($req, $res, $args) {
    $myService = $this->myService;

    return $res;
});

Slim uses __get() and __isset() magic methods that defer to the application’s container for all properties that do not already exist on the application instance.

Required services

Your container MUST implement these required services. If you use Slim’s built-in container, these are provided for you. If you choose a third-party container, you must define these required services on your own.

settings

Associative array of application settings, including keys httpVersion, outputBuffering,responseChunkSize and determineRouteBeforeAppMiddleware.

environment

Instance of \Slim\Interfaces\Http\EnvironmentInterface.

request

Instance of \Psr\Http\Message\ServerRequestInterface.

response

Instance of \Psr\Http\Message\ResponseInterface.

router

Instance of \Slim\Interfaces\RouterInterface.

foundHandler

Instance of \Slim\Interfaces\InvocationStrategyInterface.

errorHandler

Callable invoked if application error. The callable MUST return an instance of\Psr\Http\Message\ResponseInterface and accept three arguments:

\Psr\Http\Message\ServerRequestInterface

\Psr\Http\Message\ResponseInterface

\Exception

notFoundHandler

Callable invoked if the current HTTP request URI does not match an application route. The callable MUST return an instance of \Psr\Http\Message\ResponseInterface and accept two arguments:

\Psr\Http\Message\ServerRequestInterface

\Psr\Http\Message\ResponseInterface

notAllowedHandler

Callable invoked if an application route matches the current HTTP request path but not its method. The callable MUST return an instance of \Psr\Http\Message\ResponseInterfaceand accept three arguments:

\Psr\Http\Message\ServerRequestInterface

\Psr\Http\Message\ResponseInterface

Array of allowed HTTP methods

Request

How to get the Request object

The Request Method

The Request URI

The Request Headers

Get All Headers

Get One Header

Detect Header

The Request Body

Request Helpers

Detect XHR requests

Content Type

Media Type

Character Set

Content Length

IP Address

Your Slim app’s routes and middleware are given a PSR 7 request object that represents the current HTTP request received by your web server. The request object implements the PSR 7 ServerRequestInterface with which you can inspect and manipulate the HTTP request method, headers, and body.

How to get the Request object

The PSR 7 request object is injected into your Slim application routes as the first argument to the route callback like this:

      <?php
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

$app = new \Slim\App;
$app->get('/foo', function (ServerRequestInterface $request, ResponseInterface $response) {
    // Use the PSR 7 $request object

    return $response;
});
$app->run();

Figure 1: Inject PSR 7 request into application route callback.

The PSR 7 request object is injected into your Slim application middleware as the first argument of the middleware callable like this:

      <?php
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

$app = new \Slim\App;
$app->add(function (ServerRequestInterface $request, ResponseInterface $response, callable $next) {
    // Use the PSR 7 $request object

    return $next($request, $response);
});
// Define app routes...
$app->run();

Figure 2: Inject PSR 7 request into application middleware.

The Request Method

Every HTTP request has a method that is typically one of:

GET

POST

PUT

DELETE

HEAD

PATCH

OPTIONS

You can inspect the HTTP request’s method with the Request object method appropriately named getMethod().

      $method = $request->getMethod();

Because this is a common task, Slim’s built-in PSR 7 implementation also provides these proprietary methods that return true or false.

$request->isGet()

$request->isPost()

$request->isPut()

$request->isDelete()

$request->isHead()

$request->isPatch()

$request->isOptions()

It is possible to fake or override the HTTP request method. This is useful if, for example, you need to mimic a PUT request using a traditional web browser that only supports GET or POSTrequests.

There are two ways to override the HTTP request method. You can include a _METHODparameter in a POST request’s body. The HTTP request must use the application/x-www-form-urlencoded content type.

      POST /path HTTP/1.1
Host: example.com
Content-type: application/x-www-form-urlencoded
Content-length: 22

data=value&_METHOD=PUT

Figure 3: Override HTTP method with _METHOD parameter.

You can also override the HTTP request method with a custom X-Http-Method-OverrideHTTP request header. This works with any HTTP request content type.

      POST /path HTTP/1.1
Host: example.com
Content-type: application/json
Content-length: 16
X-Http-Method-Override: PUT

{"data":"value"}

Figure 4: Override HTTP method with X-Http-Method-Override header.

You can fetch the original (non-overridden) HTTP method with the PSR 7 Request object’s method named getOriginalMethod().

The Request URI

Every HTTP request has a URI that identifies the requested application resource. The HTTP request URI has several parts:

Scheme (e.g. http or https)

Host (e.g. example.com)

Port (e.g. 80 or 443)

Path (e.g. /users/1)

Query string (e.g. sort=created&dir=asc)

You can fetch the PSR 7 Request object’s URI with its getUri() method:

      $uri = $request->getUri();

The PSR 7 Request object’s URI is itself an object that provides the following methods to inspect the HTTP request’s URL parts:

getScheme()

getHost()

getPort()

getPath()

getBasePath()

getQuery() (returns string)

getQueryParams() (returns associative array)

Base Path

If your Slim application's front-controller lives in a physical subdirectory beneath your document root directory, you can fetch the HTTP request's physical base path (relative to the document root) with the Uri object's getBasePath() method. This will be an empty string if the Slim application is installed in the document root's top-most directory.

The Request Headers

Every HTTP request has headers. These are metadata that describe the HTTP request but are not visible in the request’s body. Slim’s PSR 7 Request object provides several methods to inspect its headers.

Get All Headers

You can fetch all HTTP request headers as an associative array with the PSR 7 Request object’s getHeaders() method. The resultant associative array’s keys are the header names and its values are themselves a numeric array of string values for their respective header name.

      $headers = $request->getHeaders();
foreach ($headers as $name => $values) {
    echo $name . ": " . implode(", ", $values);
}

Figure 5: Fetch and iterate all HTTP request headers as an associative array.

Get One Header

You can get a single header’s value(s) with the PSR 7 Request object’s getHeader($name)method. This returns an array of values for the given header name. Remember, a single HTTP header may have more than one value!

      $headerValueArray = $request->getHeader('Accept');

Figure 6: Get values for a specific HTTP header.

You may also fetch a comma-separated string with all values for a given header with the PSR 7 Request object’s getHeaderLine($name) method. Unlike the getHeader($name) method, this method returns a comma-separated string.

      $headerValueString = $request->getHeaderLine('Accept');

Figure 7: Get single header's values as comma-separated string.

Detect Header

You can test for the presence of a header with the PSR 7 Request object’s hasHeader($name)method.

      if ($request->hasHeader('Accept')) {
    // Do something
}

Figure 8: Detect presence of a specific HTTP request header.

The Request Body

Every HTTP request has a body. If you are building a Slim application that consumes JSON or XML data, you can use the PSR 7 Request object’s getParsedBody() method to parse the HTTP request body into a native PHP format. Slim can parse JSON, XML, and URL-encoded data out of the box.

      $parsedBody = $request->getParsedBody();

Figure 9: Parse HTTP request body into native PHP format

JSON requests are converted into a PHP object with json_decode($input).

XML requests are converted into a SimpleXMLElement withsimplexml_load_string($input).

URL-encoded requests are converted into a PHP array with parse_str($input).

Technically speaking, Slim’s PSR 7 Request object represents the HTTP request body as an instance of \Psr\Http\Message\StreamInterface. You can get the HTTP request bodyStreamInterface instance with the PSR 7 Request object’s getBody() method. ThegetBody() method is preferable if the incoming HTTP request size is unknown or too large for available memory.

      $body = $request->getBody();

Figure 10: Get HTTP request body

The resultant \Psr\Http\Message\StreamInterface instance provides the following methods to read and iterate its underlying PHP resource.

getSize()

tell()

eof()

isSeekable()

seek()

rewind()

isWritable()

write($string)

isReadable()

read($length)

getContents()

getMetadata($key = null)

Request Helpers

Slim’s PSR 7 Request implementation provides these additional proprietary methods to help you further inspect the HTTP request.

Detect XHR requests

You can detect XHR requests with the Request object’s isXhr() method. This method detects the presence of the X-Requested-With HTTP request header and ensures its value isXMLHttpRequest.

      POST /path HTTP/1.1
Host: example.com
Content-type: application/x-www-form-urlencoded
Content-length: 7
X-Requested-With: XMLHttpRequest

foo=bar

Figure 11: Example XHR request.

      if ($request->isXhr()) {
    // Do something
}

Content Type

You can fetch the HTTP request content type with the Request object’s getContentType()method. This returns the Content-Type header’s full value as provided by the HTTP client.

      $contentType = $request->getContentType();

Media Type

You may not want the complete Content-Type header. What if, instead, you only want the media type? You can fetch the HTTP request media type with the Request object’sgetMediaType() method.

      $mediaType = $request->getMediaType();

You can fetch the appended media type parameters as an associative array with the Request object’s getMediaTypeParams() method.

      $mediaParams = $request->getMediaTypeParams();

Character Set

One of the most common media type parameters is the HTTP request character set. The Request object provides a dedicated method to retrieve this media type parameter.

      $charset = $request->getContentCharset();

Content Length

You can fetch the HTTP request content length with the Request object’s getContentLength()method.

      $length = $request->getContentLength();

IP Address

You can fetch the HTTP request’s source IP address with the Request object’s getIp()method. This method respects the X-Forwarded-For header, if present.

      $ip = $request->getIp();

Response

How to get the Response object

The Response Status

The Response Headers

Get All Headers

Get One Header

Detect Header

Set Header

Append Header

Remove Header

The Response Body

Your Slim app’s routes and middleware are given a PSR 7 response object that represents the current HTTP response to be returned to the client. The response object implements the PSR 7 ResponseInterface with which you can inspect and manipulate the HTTP response status, headers, and body.

How to get the Response object

The PSR 7 response object is injected into your Slim application routes as the second argument to the route callback like this:

      <?php
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

$app = new \Slim\App;
$app->get('/foo', function (ServerRequestInterface $request, ResponseInterface $response) {
    // Use the PSR 7 $response object

    return $response;
});
$app->run();

Figure 1: Inject PSR 7 response into application route callback.

The PSR 7 response object is injected into your Slim application middleware as the second argument of the middleware callable like this:

      <?php
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

$app = new \Slim\App;
$app->add(function (ServerRequestInterface $request, ResponseInterface $response, callable $next) {
    // Use the PSR 7 $response object

    return $next($request, $response);
});
// Define app routes...
$app->run();

Figure 2: Inject PSR 7 response into application middleware.

The Response Status

Every HTTP response has a numeric status code. The status code identifies the type of HTTP response to be returned to the client. The PSR 7 Response object’s default status code is 200(OK). You can get the PSR 7 Response object’s status code with the getStatusCode()method like this.

      $status = $response->getStatusCode();

Figure 3: Get response status code.

You can copy a PSR 7 Response object and assign a new status code like this:

      $newResponse = $response->withStatus(302);

Figure 4: Create response with new status code.

The Response Headers

Every HTTP response has headers. These are metadata that describe the HTTP response but are not visible in the response’s body. Slim’s PSR 7 Response object provides several methods to inspect and manipulate its headers.

Get All Headers

You can fetch all HTTP response headers as an associative array with the PSR 7 Response object’s getHeaders() method. The resultant associative array’s keys are the header names and its values are themselves a numeric array of string values for their respective header name.

      $headers = $response->getHeaders();
foreach ($headers as $name => $values) {
    echo $name . ": " . implode(", ", $values);
}

Figure 5: Fetch and iterate all HTTP response headers as an associative array.

Get One Header

You can get a single header’s value(s) with the PSR 7 Response object’s getHeader($name)method. This returns an array of values for the given header name. Remember, a single HTTP header may have more than one value!

      $headerValueArray = $response->getHeader('Vary');

Figure 6: Get values for a specific HTTP header.

You may also fetch a comma-separated string with all values for a given header with the PSR 7 Response object’s getHeaderLine($name) method. Unlike the getHeader($name) method, this method returns a comma-separated string.

      $headerValueString = $response->getHeaderLine('Vary');

Figure 7: Get single header's values as comma-separated string.

Detect Header

You can test for the presence of a header with the PSR 7 Response object’shasHeader($name) method.

      if ($response->hasHeader('Vary')) {
    // Do something
}

Figure 8: Detect presence of a specific HTTP header.

Set Header

You can set a header value with the PSR 7 Response object’s withHeader($name, $value)method.

      $newResponse = $oldResponse->withHeader('Content-type', 'application/json');

Figure 9: Set HTTP header

Reminder

The Response object is immutable. This method returns a copy of the Response object that has the new header value. This method is destructive, and it replaces existing header values already associated with the same header name.

Append Header

You can append a header value with the PSR 7 Response object’s withAddedHeader($name, $value) method.

      $newResponse = $oldResponse->withAddedHeader('Allow', 'PUT');

Figure 10: Append HTTP header

Reminder

Unlike the withHeader() method, this method appends the new value to the set of values that already exist for the same header name. The Response object is immutable. This method returns a copy of the Response object that has the appended header value.

Remove Header

You can remove a header with the Response object’s withoutHeader($name) method.

      $newResponse = $oldResponse->withoutHeader('Allow');

Figure 11: Remove HTTP header

Reminder

The Response object is immutable. This method returns a copy of the Response object that has the appended header value.

The Response Body

An HTTP response typically has a body. Slim provides a PSR 7 Response object with which you can inspect and manipulate the eventual HTTP response’s body.

Just like the PSR 7 Request object, the PSR 7 Response object implements the body as an instance of \Psr\Http\Message\StreamInterface. You can get the HTTP response bodyStreamInterface instance with the PSR 7 Response object’s getBody() method. ThegetBody() method is preferable if the outgoing HTTP response length is unknown or too large for available memory.

      $body = $response->getBody();

Figure 12: Get HTTP response body

The resultant \Psr\Http\Message\StreamInterface instance provides the following methods to read from, iterate, and write to its underlying PHP resource.

getSize()

tell()

eof()

isSeekable()

seek()

rewind()

isWritable()

write($string)

isReadable()

read($length)

getContents()

getMetadata($key = null)

Most often, you’ll need to write to the PSR 7 Response object. You can write content to theStreamInterface instance with its write() method like this:

      $body = $response->getBody();
$body->write('Hello');

Figure 13: Write content to the HTTP response body

You can also replace the PSR 7 Response object’s body with an entirely newStreamInterface instance. This is particularly useful when you want to pipe content from a remote destination (e.g. the filesystem or a remote API) into the HTTP response. You can replace the PSR 7 Response object’s body with its withBody(StreamInterface $body)method. Its argument MUST be an instance of \Psr\Http\Message\StreamInterface.

      $newStream = new \GuzzleHttp\Psr7\LazyOpenStream('/path/to/file', 'r');
$newResponse = $oldResponse->withBody($newStream);

Figure 13: Replace the HTTP response body

Reminder

The Response object is immutable. This method returns a copy of the Response object that contains the new body.

Router

How to create routes

GET Route

POST Route

PUT Route

DELETE Route

OPTIONS Route

PATCH Route

Custom Route

Route callbacks

Writing content to the response

Closure binding

Route strategies

Route placeholders

Format

Regular expression matching

Route names

Route groups

Route middleware

The Slim Framework’s router is built on top of the nikic/fastroute component, and it is remarkably fast and stable.

How to create routes

You can define application routes using proxy methods on the \Slim\App instance. The Slim Framework provides methods for the most popular HTTP methods.

GET Route

You can add a route that handles only GET HTTP requests with the Slim application’s get()method. It accepts two arguments:

The route pattern (with optional named placeholders)

The route callback

      $app = new \Slim\App();
$app->get('/books/{id}', function ($request, $response, $args) {
    // Show book identified by $args['id']
});

POST Route

You can add a route that handles only POST HTTP requests with the Slim application’spost() method. It accepts two arguments:

The route pattern (with optional named placeholders)

The route callback

      $app = new \Slim\App();
$app->post('/books', function ($request, $response, $args) {
    // Create new book
});

PUT Route

You can add a route that handles only PUT HTTP requests with the Slim application’s put()method. It accepts two arguments:

The route pattern (with optional named placeholders)

The route callback

      $app = new \Slim\App();
$app->put('/books/{id}', function ($request, $response, $args) {
    // Update book identified by $args['id']
});

DELETE Route

You can add a route that handles only DELETE HTTP requests with the Slim application’sdelete() method. It accepts two arguments:

The route pattern (with optional named placeholders)

The route callback

      $app = new \Slim\App();
$app->delete('/books/{id}', function ($request, $response, $args) {
    // Delete book identified by $args['id']
});

OPTIONS Route

You can add a route that handles only OPTIONS HTTP requests with the Slim application’soptions() method. It accepts two arguments:

The route pattern (with optional named placeholders)

The route callback

      $app = new \Slim\App();
$app->options('/books/{id}', function ($request, $response, $args) {
    // Return response headers
});

PATCH Route

You can add a route that handles only PATCH HTTP requests with the Slim application’spatch() method. It accepts two arguments:

The route pattern (with optional named placeholders)

The route callback

      $app = new \Slim\App();
$app->patch('/books/{id}', function ($request, $response, $args) {
    // Apply changes to book identified by $args['id']
});

Custom Route

You can add a route that handles multiple HTTP request methods with the Slim application’smap() method. It accepts three arguments:

Array of HTTP methods

The route pattern (with optional named placeholders)

The route callback

      $app = new \Slim\App();
$app->map(['GET', 'POST'], '/books', function ($request, $response, $args) {
    // Create new book or list all books
});

Route callbacks

Each routing method described above accepts a callback routine as its final argument. This argument can be any PHP callable, and by default it accepts three arguments.

Request

The first argument is a Psr\Http\Message\ServerRequestInterface object that represents the current HTTP request.

Response

The second argument is a Psr\Http\Message\ResponseInterface object that represents the current HTTP response.

Arguments

The third argument is an associative array that contains values for the current route’s named placeholders.

Writing content to the response

There are two ways you can write content to the HTTP response. First, you can simply echo()content from the route callback. This content will be appended to the current HTTP response object. Second, you can return a Psr\Http\Message\ResponseInterface object.

Closure binding

If you use a Closure instance as the route callback, the closure’s state is bound to the\Slim\App instance. This means you can access the \Slim\App object from inside the route callback with $this. Because the \Slim\App itself composes the DI container, you can quickly access any services registered with the DI container from inside the Closure callback like this:

      $app = new \Slim\App();
$app->get('/hello/{name}', function ($request, $response, $args) {
    // Use app HTTP cookie service
    $this->cookies->set('name', [
        'name' => $args['name'],
        'expires' => '7 days'
    ]);
});

Route strategies

The route callback signature is determined by a route strategy. By default, Slim expects route callbacks to accept the request, response, and an array of route placeholder arguments. This is called the RequestResponse strategy. However, you can change the expected route callback signature by simply using a different strategy. As an example, Slim provides an alternative strategy called RequestResponseArgs that accepts request and response, plus each route placeholder as a separate argument. Here is an example of using this alternative strategy; simply replace the foundHandler dependency provided by the default\Slim\Container:

      $c = new \Slim\Container();
$c['foundHandler'] = function() {
    return new \Slim\Handlers\Strategies\RequestResponseArgs();
};

$app = new \Slim\App($c);
$app->get('/hello/{name}', function ($request, $response, $name) {
    return $response->write($name);
});

You can provide your own route strategy by implementing the\Slim\Interfaces\InvocationStrategyInterface.

Route placeholders

Each routing method described above accepts a URL pattern that is matched against the current HTTP request URI. Route patterns may use named placeholders to dynamically match HTTP request URI segments.

Format

A route pattern placeholder starts with a {, followed by the placeholder name, ending with a}. This is an example placeholder named name:

      $app = new \Slim\App();
$app->get('/hello/{name}', function ($request, $response, $args) {
    echo "Hello, " . $args['name'];
});

Regular expression matching

By default the placeholders are written inside {} and can accept any values. However, placeholders can also require the HTTP request URI to match a particular regular expression. If the current HTTP request URI does not match a placeholder regular expression, the route is not invoked. This is an example placeholder named id that requires a digit.

      $app = new \Slim\App();
$app->get('/users/{id:[0-9]+}', function ($request, $response, $args) {
    // Find user identified by $args['id']
});

Route names

Application route’s can be assigned a name. This is useful if you want to programmatically generate a URL to a specific route with the router’s pathFor() method. Each routing method described above returns a \Slim\Route object, and this object exposes a setName()method.

      $app = new \Slim\App();
$app->get('/hello/{name}', function ($request, $response, $args) {
    echo "Hello, " . $args['name'];
})->setName('hello');

You can generate a URL for this named route with the application router’s pathFor() method.

      echo $app->router->pathFor('hello', [
    'name' => 'Josh'
]);
// Outputs "/hello/Josh"

The router’s pathFor() method accepts two arguments:

The route name

Associative array of route pattern placeholders and replacement values

Route groups

To help organize routes into logical groups, the \Slim\App also provides a group() method. Each group’s route pattern is prepended to the routes or groups contained within it, and any placeholder arguments in the group pattern are ultimately made available to the nested routes:

      $app = new \Slim\App();
$app->group('/users/{id:[0-9]+}', function () {
    $this->map(['GET', 'DELETE', 'PATCH', 'PUT'], '', function ($request, $response, $args) {
        // Find, delete, patch or replace user identified by $args['id']
    })->setName('user');
    $this->get('/reset-password', function ($request, $response, $args) {
        // Route for /users/{id:[0-9]+}/reset-password
        // Reset the password for user identified by $args['id']
    })->setName('user-password-reset');
});

Note inside the group closure, $this is used instead of $app. Slim binds the closure to the application instance for you, just like it is the case with route callbacks.

Route middleware

You can also attach middleware to any route or route group. Learn more.

500 System Error Handler

Things go wrong. You can’t predict errors, but you can anticipate them. Each Slim Framework application has an error handler that receives all uncaught PHP exceptions. This error handler also receives the current HTTP request and response objects, too. The error handler must prepare and return an appropriate Response object to be returned to the HTTP client.

Default error handler

The default error handler is very basic. It sets the Response status code to 500, it sets the Response content type to text/html, and appends a generic error message into the Response body.

This is probably not appropriate for production applications. You are strongly encouraged to implement your own Slim application error handler.

The default error handler can also include detailed error diagnostic information. To enable this you need to set the displayErrorDetails setting to true:

      $configuration = [
    'settings' => [
        'displayErrorDetails' => true,
    ],
];
$c = new \Slim\Container($configuration);
$app = new \Slim\App($c);

Custom error handler

A Slim Framework application’s error handler is a Pimple service. You can substitute your own error handler by defining a custom Pimple factory method with the application container.

There are two ways to inject handlers:

Pre App

      $c = new \Slim\Container();
$c['errorHandler'] = function ($c) {
    return function ($request, $response, $exception) use ($c) {
        return $c['response']->withStatus(500)
                             ->withHeader('Content-Type', 'text/html')
                             ->write('Something went wrong!');
    };
};
$app = new \Slim\App($c);

Post App

      $app = new \Slim\App();
$c = $app->getContainer();
$c['errorHandler'] = function ($c) {
    return function ($request, $response, $exception) use ($c) {
        return $c['response']->withStatus(500)
                             ->withHeader('Content-Type', 'text/html')
                             ->write('Something went wrong!');
    };
};

In this example, we define a new errorHandler factory that returns a callable. The returned callable accepts three arguments:

A \Psr\Http\Message\ServerRequestInterface instance

A \Psr\Http\Message\ResponseInterface instance

A \Exception instance

The callable MUST return a new \Psr\Http\Message\ResponseInterface instance as is appropriate for the given exception.

Disabling

To completely disable Slim’s error handling, simply remove the error handler from the container:

      unset($app->getContainer()['errorHandler']);

You are now responsible for handling any exceptions that occur in your application as they will not be handled by Slim.

404 Not Found Handler

If your Slim Framework application does not have a route that matches the current HTTP request URI, the application invokes its Not Found handler and returns a HTTP/1.1 404 Not Found response to the HTTP client.

Default Not Found handler

Each Slim Framework application has a default Not Found handler. This handler sets the Response status to 404, it sets the content type to text/html, and it writes a simple explanation to the Response body.

Custom Not Found handler

A Slim Framework application’s Not Found handler is a Pimple service. You can substitute your own Not Found handler by defining a custom Pimple factory method with the application container.

      $c = new \Slim\Container(); //Create Your container

//Override the default Not Found Handler
$c['notFoundHandler'] = function ($c) {
    return function ($request, $response) use ($c) {
        return $c['response']
            ->withStatus(404)
            ->withHeader('Content-Type', 'text/html')
            ->write('Page not found');
    };
};

//Create Slim
$app = new \Slim\App($c);

//... Your code

In this example, we define a new notFoundHandler factory that returns a callable. The returned callable accepts two arguments:

A \Psr\Http\Message\ServerRequestInterface instance

A \Psr\Http\Message\ResponseInterface instance

The callable MUST return an appropriate \Psr\Http\Message\ResponseInterface instance.

405 Not Allowed Handler

If your Slim Framework application has a route that matches the current HTTP request URI but NOT the HTTP request method, the application invokes its Not Allowed handler and returns a HTTP/1.1 405 Not Allowed response to the HTTP client.

Default Not Allowed handler

Each Slim Framework application has a default Not Allowed handler. This handler sets the Response status to 405, it sets the content type to text/html, it adds a Allowed: HTTP header with a comma-delimited list of allowed HTTP methods, and it writes a simple explanation to the Response body.

Custom Not Allowed handler

A Slim Framework application’s Not Allowed handler is a Pimple service. You can substitute your own Not Allowed handler by defining a custom Pimple factory method with the application container.

      // Create Slim
$app = new \Slim\App();
// get the app's di-container
$c = $app->getContainer();
$c['notAllowedHandler'] = function ($c) {
    return function ($request, $response, $methods) use ($c) {
        return $c['response']
            ->withStatus(405)
            ->withHeader('Allow', implode(', ', $methods))
            ->withHeader('Content-type', 'text/html')
            ->write('Method must be one of: ' . implode(', ', $methods));
};

N.B Check out Not Found docs for pre-slim creation method using a new instance of\Slim\Container

In this example, we define a new notAllowedHandler factory that returns a callable. The returned callable accepts three arguments:

A \Psr\Http\Message\ServerRequestInterface instance

A \Psr\Http\Message\ResponseInterface instance

A numeric array of allowed HTTP method names

The callable MUST return an appropriate \Psr\Http\Message\ResponseInterface instance.

Templates

Slim does not have a view layer like traditional MVC frameworks. Instead, Slim’s “view” is the HTTP response. Each Slim application route is responsible for preparing and returning an appropriate PSR 7 response object.

Slim’s “view” is the HTTP response.

The slim/twig-view component

That being said, Slim does provide the optional slim/twig-view PHP component to help you render Twig templates to a PSR 7 Response object. This component is available on Packagist, and it’s easy to install with Composer like this:

      composer require slim/twig-view

Figure 1: Install slim/twig-view component.

Next, you need to register the component as a service on the Slim app’s container like this:

      <?php
// Create container
$container = new \Slim\Container;

// Register component on container
$container['view'] = function ($c) {
    $view = new \Slim\Views\Twig('path/to/templates', [
        'cache' => 'path/to/cache'
    ]);
    $view->addExtension(new \Slim\Views\TwigExtension(
        $c['router'],
        $c['request']->getUri()
    ));

    return $view;
};

Figure 2: Register slim/twig-view component with container.

Note : “cache” could be set to false to disable it, see also ‘auto_reload’ option, usefull in development environnement. For more information, see Twig environment options

Now you can use the slim/twig-view component service inside an app route to render a template and write it to a PSR 7 Response object like this:

      // Create app
$app = new \Slim\App($container);

// Render Twig template in route
$app->get('/hello/{name}', function ($request, $response, $args) {
    return $this->view->render($response, 'profile.html', [
        'name' => $args['name']
    ]);
})->setName('profile');

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

Figure 3: Render template with slim/twig-view container service.

In this example, $this->view invoked inside the route callback is a reference to the\Slim\Views\Twig instance returned by the view container service. The \Slim\Views\Twiginstance’s render() method accepts a PSR 7 Response object as its first argument, the Twig template path as its second argument, and an array of template variables as its final argument. The render() method returns a new PSR 7 Response object whose body is the rendered Twig template.

The path_for() method

The slim/twig-view component exposes a custom path_for() function to your Twig templates. You can use this function to generate complete URLs to any named route in your Slim application. The path_for() function accepts two arguments:

A route name

A hash of route placeholder names and replacement values

The second argument’s keys should correspond to the selected route’s pattern placeholders. This is an example Twig template that draws a link URL for the “profile” named route shown in the example Slim application above.

      {% extends "layout.html" %}

{% block body %}
<h1>User List</h1>
<ul>
    <li><a href="{{ path_for('profile', { 'name': 'josh' }) }}">Josh</a></li>
</ul>
{% endblock %}

Other template systems

You are not limited to the slim/twig-view component. You can use any PHP template system assuming you ultimately write the rendered template output to the PSR 7 Response object’s body.

HTTP Caching

Slim 3 uses the optional standalone slimphp/Slim-HttpCache PHP component for HTTP caching. You can use this component to create and return responses that contain Cache,Expires, ETag, and Last-Modified headers that control when and how long application output is retained by client-side caches.

Installation

Execute this bash command from your project’s root directory:

      composer require slim/http-cache

Usage

The slimphp/Slim-HttpCache component contains a service provider and an application middleware. You should add both to your application like this:

      // Register service provider with the container
$container = new \Slim\Container;
$container['cache'] = function () {
    new \Slim\HttpCache\CacheProvider();
};

// Add middleware to the application
$app = new \Slim\App($container);
$app->add(new \Slim\HttpCache\Cache('public', 86400));

// Create your application routes...

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

ETag

Use the service provider’s withEtag() method to create a Response object with the desiredETag header. This method accepts a PSR7 response object, and it returns a cloned PSR7 response with the new HTTP header.

      $app->get('/foo', function ($req, $res, $args) {
    $resWithEtag = $this->cache->withEtag($res, 'abc');

    return $resWithEtag;
});

Expires

Use the service provider’s withExpires() method to create a Response object with the desired Expires header. This method accepts a PSR7 response object, and it returns a cloned PSR7 response with the new HTTP header.

      $app->get('/bar',function ($req, $res, $args) {
    $resWithExpires = $this->cache->withExpires($res, time() + 3600);

    return $resWithExpires;
});

Last-Modified

Use the service provider’s withLastModified() method to create a Response object with the desired Last-Modified header. This method accepts a PSR7 response object, and it returns a cloned PSR7 response with the new HTTP header.

      //Example route with LastModified
$app->get('/foobar',function ($req, $res, $args) {
    $resWithLastMod = $this->cache->withLastModified($res, time() - 3600);

    return $resWithLastMod;
});

CSRF Protection

Slim 3 uses the optional standalone slimphp/Slim-Csrf PHP component to protect your application from CSRF (cross-site request forgery). This component generates a unique token per request that validates subsequent POST requests from client-side HTML forms.

Installation

Execute this bash command from your project’s root directory:

      composer require slim/csrf

Usage

The slimphp/Slim-Csrf component contains an application middleware. Add it to your application like this:

      // Add middleware to the application
$app = new \Slim\App;
$app->add(new \Slim\Csrf\Guard);

// Create your application routes...

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

Fetch the CSRF token name and value

The latest CSRF token’s name and value are available as attributes on the PSR7 request object. The CSRF token name and value are unique for each request. You can fetch the current CSRF token name and value like this.

      $app->get('/foo', function ($req, $res, $args) {
    // Fetch CSRF token name and value
    $name = $req->getAttribute('csrf_name');
    $value = $req->getAttribute('csrf_value');

    // TODO: Render template with HTML form and CSRF token hidden field
});

You should pass the CSRF token name and value to the template so they may be submitted with HTML form POST requests. They are often stored as a hidden field with HTML forms.

Flash Messages

Coming soon.

Branching Strategy

The Slim Framework uses a simple branching strategy. There is one master branch, and themaster branch HEAD reference points to the latest unstable code. Each stable release is denoted with a numeric tag (e.g., 3.0.0).

Contributor Guidelines

I encourage everyone to contribute to the Slim Framework project. You can find the latest code on GitHub at https://github.com/slimphp/Slim.

Issue Tracker

You can find outstanding issues on the GitHub Issue Tracker. If you intend to work on a specific issue, leave a comment on the appropriate thread to inform other project contributors.

Pull Requests

Each pull request should contain only one new feature or improvement.

Pull requests should be submitted to the master branch

Code Style

All pull requests must use the PSR-2 code style.

Code MUST use the PSR-1 code style.

Code MUST use 4 spaces for indenting, not tabs.

There MUST NOT be a hard limit on line length; the soft limit MUST be 120 characters; lines SHOULD be 80 characters or less.

There MUST be one blank line after the namespace declaration, and there MUST be one blank line after the block of use declarations.

Opening braces for classes MUST go on the next line, and closing braces MUST go on the next line after the body.

Opening braces for methods MUST go on the next line, and closing braces MUST go on the next line after the body.

Visibility MUST be declared on all properties and methods; abstract and final MUST be declared before the visibility; static MUST be declared after the visibility.

Control structure keywords MUST have one space after them; method and function calls MUST NOT.

Opening braces for control structures MUST go on the same line, and closing braces MUST go on the next line after the body.

Opening parentheses for control structures MUST NOT have a space after them, and closing parentheses for control structures MUST NOT have a space before.