Skip to content

Slim Framework Documentation

codeguy edited this page Mar 5, 2011 · 78 revisions

Documentation (Release Branch)

Table of Contents

Slim lets you build a complete PHP web service with only a single PHP file. The typical process for writing a Slim application is:

//1. Require Slim
require('Slim/Slim.php');

//2. Initialize Slim
Slim::init();

//3. Define routes
Slim::get('/books/:id', function ($id) {
	//Show book with id = $id
});

//4. Run Slim
Slim::run();
  • PHP 5.1 or newer
  • Encrypted Cookies require mcrypt extension

Require Slim

The first thing you must do is require() Slim into your bootstrap file. If you move the Slim/ directory elsewhere on your file system, it is important that you keep Slim's dependencies in the same directory as Slim.php. Keeping the files together enables you to only require Slim.php and have the other files required automatically for you. Assuming the Slim/ directory is on your include path, you only need to call:

require 'Slim/Slim.php';

Back to Top

After you require Slim, initialize your Slim application with:

Slim::init();

The Slim::init() method accepts an optional associative array to customize the Slim application settings during application initialization. You can see a list of available settings below. If you use a custom View in your Slim app, you can set your custom View (among other options) when you initialize your Slim application.

Let's pretend I have a custom View class called TwigView. I would pass the name or an instance of my TwigView class into the Slim::init() method like this:

//As a string
Slim::init(array(
    'view' => 'TwigView'   
));

//Or, as an instance
Slim::init(array(
    'view' => new TwigView() 
));

It is important that you only initialize Slim once, so use only one of the examples above to specify your custom View class.

Back to Top

To configure your Slim application, pass an associative array into the Slim::init() method. The available settings are:

log.enable

Enable or disable application logging.

Data Type
boolean
Default
false

log.path

Relative or absolute path to log files directory. Directory must be writable by PHP. This setting is only applicable if using the default Slim logger.

Data Type
string
Default
./logs

log.logger

An instance of a custom logger class that implements the requried interface described in the Custom Logger section below. Leave NULL to use default Slim logger.

Data Type
Object
Default
null

log.level

The level of messages to log using the default Slim logger. See Default Logger below for a full description. This setting is only applicable if using the default Slim logger.

Data Type
int
Default
4

debug

Enable or disable application debugging. If true, Slim provides debugging information for Errors and Exceptions. If false, Slim will call the user-defined Error Handler instead.

Data Type
boolean
Default
true

templates_dir

Relative or absolute filesystem path to template files directory used by the application View.

Data Type
string
Default
./templates

view

Determines the View class used by the Slim application.

Data Type
If string, the name of the custom View class;
If object, a subclass of `View`;
Default
View

cookies.lifetime

Determines the lifetime of Cookies created by the Slim app.

Data Type
If integer, a valid UNIX timestamp;
If string, anything that can be parsed by `strtotime` to extrapolate a valid UNIX timestamp.
Default
20 minutes

cookies.path

Determines the default browser Cookie path if none specified with Slim::setCookie or Slim::setEncryptedCookie.

Data Type
string
Default
/

cookies.domain

Determies the default browser Cookie domain if none specified with Slim::setCookie or Slim::setEncryptedCookie.

Data Type
string
Default
null

cookies.secure

Should the Slim application transfer Cookies over SSL/HTTPS only?

Data Type
boolean
Default
false

cookies.httponly

Should the Slim application transfer Cookies using the HTTP protocol only?

Data Type
boolean
Default
false

cookies.secret_key

The secret key used for browser Cookie encryption. See Slim::setEncryptedCookie. This field is required if you use encrypted Cookies in your Slim application.

Data Type
string
Default
CHANGE_ME

cookies.cipher

The mcrypt cipher used for browser Cookie encryption. You can see a list of available ciphers at http://php.net/manual/en/mcrypt.ciphers.php.

Data Type
PHP constant (see URL above)
Default
MCRYPT_RIJNDAEL_256

cookies.cipher_mode

The mcrypt cipher mode used for browser Cookie encryption. You can see a list of available cipher modes at http://www.php.net/manual/en/mcrypt.constants.php

Data Type
PHP constant (see URL above)
Default
MCRYPT_MODE_CBC

cookies.encrypt

Should Slim::setEncryptedCookie() encrypt browser Cookie values?

Data Type
boolean
Default
true

cookies.user_id

When using Slim::setEncryptedCookie, you can ensure the encrypted cookie is only available for a given user identifier. After you authenticate a user, set this value with Slim::config('cookies.user_id', THE_USER_ID) to ensure all Cookies set during the give user's session are only available for that user.

Data Type
string
Default
DEFAULT

Any of the settings shown above may also be specified using Slim::config().

Configure Slim after initialization

Define a setting

Slim::config('foo', 'bar');

If you need to define a lot of application settings, you can do so at once by passing an associative array, like this:

Slim::config(array(
	'one' => 'A',
	'two' => 'B',
	'three' => 'C'
));

Retrieve a Setting

$settingValue = Slim::config('foo'); //returns 'bar'

If the requested setting does not exist, Slim::config() returns NULL instead.

Back to Top

Slim supports RESTful routing, allowing you to route a URL to a specific callback function. Slim also associates each route with a specific HTTP request method (GET, POST, PUT, or DELETE).

Slim will execute the first route that matches the current request. Slim first finds all routes that match the current request's method, then it examines each of these routes in the order they were added. The first matching route's callback function will then be run.

Slim::get()

Use Slim::get() to associate a callback function with a GET request URI.

//For PHP 5 >= 5.3
Slim::get('/books/:id', function ($id) {
	//Show book with id = $id
});

//For PHP 5 < 5.3
Slim::get('/books/:id', 'show_book');
function show_book($id) {
	//Show book with id = $id
}

In this example, a GET request for "/books/1" will execute the associated function, passing "1" into the function as the first parameter.

Slim::post()

Use Slim::post() to associate a callback function with a POST request URI.

//For PHP 5 >= 5.3
Slim::post('/books', function () {
	//Create a new book
});

//For PHP 5 < 5.3
Slim::post('/books', 'post_book');
function post_book() {
	//Create a new book
}

In this example, a POST request for "/books" will execute the associated function.

Slim::put()

Use Slim::put() to associate a callback function with a PUT request URI.

//For PHP 5 >= 5.3
Slim::put('/books/:id', function ($id) {
	//Update book with id = $id
});

//For PHP 5 < 5.3
Slim::put('/books/:id', 'put_book');
function put_book($id) {
	//Update book with id = $id
}

In this example, a PUT request for "/books/1" will execute the associated function and update the book with the specified ID.

Unfortunately, modern browsers do not provide native support for PUT requests. To work around this limitation, ensure your HTML form's method is "post", then add a method override parameter to your HTML form like this:

<form action="/books/1" method="post">
	... other form fields here...
	<input type="hidden" name="_METHOD" value="PUT"/>
	<input type="submit" value="Update Book"/>
</form>

Slim::delete()

Use Slim::delete() to associate a callback function with a DELETE request URI.

//For PHP 5 >= 5.3
Slim::delete('/books/:id', function ($id) {
	//Delete book with id = $id
});

//For PHP 5 < 5.3
Slim::delete('/books/:id', 'delete_book');
function delete_book($id) {
	//Delete book with id = $id
}

In this example, a DELETE request for "/books/1" will execute the associated function and delete the book with the specified ID.

Unfortunately, modern browsers do not provide native support for DELETE requests. To work around this limitation, ensure your HTML form's method is "post", then add a method override parameter to your HTML form like this:

<form action="/books/1" method="post">
	... other form fields here...
	<input type="hidden" name="_METHOD" value="DELETE"/>
	<input type="submit" value="Delete Book"/>
</form>

Back to Top

As you may have noticed above, you can embed parameters into your routes. In this example, I have two parameters in my route, ":one" and ":two".

//For PHP 5 >= 5.3
Slim::get('/books/:one/:two', function ($one, $two) {
	echo "The first paramter is " . $one;
	echo "The second parameter is " . $two;
});

//For PHP 5 < 5.3
Slim::get('/books/:one/:two', 'callback_name');
function callback_name($one, $two) {
	echo "The first paramter is " . $one;
	echo "The second parameter is " . $two;
}

To create a URL parameter, simple prepend ":" to the parameter name in the route pattern. When the route is matched to the current request, the values for each route parameter are passed into the associated callback function, in order of appearance.

Optional Route Parameters

You may also have optional route segments. These are ideal for using one route for a blog archive. To declare route parameters optional, specify your route pattern like this:

Slim::get('/archive(/:year(/:month(/:day)))', function ($year = 2010, $month = 12, $day = 05) {});

As you can see, each subsequent route segment is optional. This route will accept HTTP requests for:

/archive
/archive/2010
/archive/2010/12
/archive/2010/12/05

If an optional route segment is omitted from the HTTP request, the default values in the callback signature are used instead.

Currently, you can only use optional route segments in situations like the example above where each route segment is subsequently optional.

Back to Top

Slim lets you assign conditions to route parameters. If the specified conditions are not met, the route is not run. For example, if you needed a route whose second segment must be a valid 4-digit year, you could enforce this condition like this:

Slim::get('/archive/:year', function ($year) {
	echo "You are viewing archives from $year";
})->conditions(array('year' => '(19|20)\d\d'));

You only need to call the conditions method passing in an associative array whose keys match any of the route's parameters, and whose values are regular expressions.

Application-wide Default Route Conditions

If many of your Slim application Routes accept the same parameters and use the same conditions, you can define default application-wide Route conditions like this:

Slim_Route::setDefaultConditions(array(
	'firstName' => '[a-zA-Z]{3,}'
));

Define application-wide Route conditions before you create your Routes. When you create a Route, it will automatically be assigned any application-wide Route conditions defined with Slim_Route::setDefaultConditions(). If for whatever reason you need to get the application-wide default conditions, you can fetch them with Slim_Route::getDefaultConditions() which returns an array exactly as the default Route conditions were defined.

You may override a default Route condition by redefining the Route's condition like this:

Slim::get('/hello/:firstName', $callable)->conditions(array('firstName' => '[a-z]{10,}'));

You may append new conditions to a given Route like this:

Slim::get('/hello/:firstName/:lastName', $callable)->conditions(array('lastName' => '[a-z]{10,}'));

Back to Top

Slim also lets you assign a name to a route. Naming a route enables you to dynamically generate URLs using the Slim::urlFor helper method. When you use the Slim::urlFor helper method to create application URLs, you can freely change route patterns without breaking your application. Here is an example of a named route:

Slim::get('/hello/:name', function ($name) {
	echo "Hello, $name!";
})->name('hello');

You may now generate URLs for this route using the Slim::urlFor helper method, described next. If you need to assign a name and conditions to a route, you can chain your method calls like this:

Slim::get('/hello/:name', function ($name) {
	echo "Hello, $name!";
})->name('hello')->conditions(array('name' => '\w+'));

Back to Top

As described in the Named Routes section above, this helper method lets you dynamically create URLs for a named route so that, were a route pattern to change, your URLs would update automatically without breaking your application. This example demonstrates how to generate URLs for the named route above:

$url = Slim::urlFor(
	'hello',
	array('name' => 'Josh')
);
//$url == '/hello/Josh'

To use this helper method, you must first assign a name to a route. Next, call Slim::urlFor(). The first parameter is the name of the route, and the second parameter is an associative array used to replace the route's URL parameters with actual values.

Back to Top

A route can tell the Slim application to continue to the next matching route with Slim::pass(). When this method is invoked, the Slim application will immediately stop processing the current route and invoke the next matching route. If no subsequent matching route is found, a 404 Not Found response is sent to the client. Here is an example:

Slim::get('/foo', function () {
	Slim::pass();
});

Back to Top

It is easy to redirect the client to another URL with the Slim::redirect() method. To issue a temporary redirect, call Slim::redirect() and set the first method parameter to the destination URL:

Slim::post('/users', function () {
	//Create new user here
	Slim::redirect('/users-list');
});

Or if you wish to issue a permanent redirect, you must specify the destination URL as the first parameter and the HTTP status code as the second parameter:

Slim::post('/users', function () {
	//Create new user here
	Slim::redirect('/users-list', 301);
});

This method will automatically set the necessary HTTP Location header and status code and immediately send the redirect HTTP response to the client.

Back to Top

It is an inevitability that someone will request a page that does not exist. Slim lets you easily define a custom Not Found handler with Slim::notFound(). The Not Found handler will be invoked when a matching route is not found for the current HTTP request. This method may be invoked in two different contexts.

When defining the Not Found handler

If you invoke Slim::notFound() and specify a callable object as its first parameter, this method will register the callable object as the Not Found handler. However, the registered handler will not be invoked.

//For PHP 5 >= 5.3
Slim::notFound(function () {
	Slim::render('404.html');
});

//For PHP 5 < 5.3
Slim::notFound('custom_not_found_callback');
function custom_not_found_callback() {
	Slim::render('404.html');
}

When invoking the Not Found callback

If you invoke Slim::notFound() without any parameters, this method assumes you wish to invoke a previously registered Not Found handler.

Slim::get('/hello/:name', function ($name) {
	if( $name === 'Waldo' ){
		Slim::notFound();
	} else {
		echo "Hello, $name";
	}
});

Back to Top

Slim routes automatically provide pretty URLs and intelligent redirection — behavior very similar to the Apache web server. Here are two example routes:

Slim::get('/services/', function () {});

Slim::get('/contact', function () {});

At first glance, both routes appear similar. However, in the first route example, the canonical URL for the services route has a trailing slash. It acts the same as a folder; accessing it without a trailing slash will prompt Slim to redirect to the canonical URL with the trailing slash.

In the second example, the URL is defined without a trailing slash. Therefore, it behaves similar to a file. Accessing it with a trailing slash will cause a 404 Not Found error.

Why did I choose this behavior? This allows relative URLs to continue working if users access the page and forget the trailing slash. This is consistent with Apache's behavior. URLs will also stay unique, and search engines should not index the same page twice with different URLs.

Slim will work with or without URL rewriting. To use Slim without URL rewriting, you should include "index.php" in the request URL. Here is an example; assume the Slim application code is in the file index.php located at the top level of your document root.

Slim::init();
Slim::get('/hello/:first/:last', function ($firstName, $lastName) {
    echo "Hello $firstName $lastName";
});
Slim::run();

You can access this route at this URL:

/index.php/hello/Josh/Lockhart

A Slim application has a Request object that represents the current HTTP request. The Request object provides the HTTP request headers, request content type, request method, request uri, parameters, and raw body. You can access the Request object like this:

$request = Slim::request(); //Returns Slim_Http_Request object

Request Parameters

An HTTP request may have associated parameters (not to be confused with Route parameters above). You can access the HTTP request parameters like this:

$paramValue = Slim::request()->params('paramName');

This method will first search PUT parameters, then POST parameters, then GET parameters. If no parameter is found, NULL is returned. If you only wish to search for a specific type of parameter, you can use these methods instead:

//GET parameter
$paramValue = Slim::request()->get('paramName');

//POST parameter
$paramValue = Slim::request()->post('paramName');

//PUT parameter
$paramValue = Slim::request()->put('paramName');

If a parameter does not exist, each method above will return NULL. You can also call each function above without a parameter name to get an array of all parameters.

$allGetParams = Slim::request()->get();
$allPostParams = Slim::request()->post();
$allPutParams = Slim::request()->put();

Request Method

Every HTTP request has a method (ie. GET, POST, PUT, DELETE, or HEAD). You can check for the Request method like this:

//What IS the request method?
$method = Slim::request()->getMethod(); //ie. "PUT"

//Is this a GET request?
Slim::request()->isGet(); //true or false

//Is this a POST request?
Slim::request()->isPost(); //true or false

//Is this a PUT request?
Slim::request()->isPut(); //true or false

//Is this a DELETE request?
Slim::request()->isDelete(); //true or false

//Is this a HEAD request?
Slim::request()->isHead(); //true or false

//Is this a request made with Ajax/XHR?
Slim::request()->isAjax(); //true or false

Regarding AJAX detection: When using a Javascript framework like MooTools or jQuery, in most cases Slim can automatically detect AJAX requests because the Javascript framework will set the 'X-Requested-With' HTTP request header for you. However, you can force Slim to assume an HTTP request is made via AJAX by setting a GET, POST, or PUT parameter called "isajax".

Request URI

Every request to your Slim application will have a root URI and a resource URI. For this example, assume the Slim application is installed in a physical subdirectory /foo/ beneath your web document root. Also assume the full HTTP request URL is /foo/books/1. In this example the root URI is /foo (the path to the physical directory in which your Slim app is installed) and the resource URI is /books/1 (the path to a resource relative to your application).

You can get the Request's root URI and resource URI like this:

//Get the Request root URI
$rootUri = Slim::request()->getRootUri();

//Get the Request resource URI
$resourceUri = Slim::request()->getResourceUri();

Request Content-Type and Body

If you create a RESTful API with Slim, it is important that you are able to get the Content-Type and raw body of an HTTP request. You can get the Request Content-Type and raw body like this:

//Get the Request content type
$contentType = Slim::request()->getContentType(); //ie. "application/json"

//Get the Request body
$body = Slim::request()->getBody();

Request Headers

Slim will automatically parse all HTTP request headers. You can access the Request headers like this:

//All request headers
$headers = Slim::request()->headers(); //returns array

//Get only the ACCEPT_CHARSET header
$charsets = Slim::request()->headers('ACCEPT_CHARSET'); //returns string or NULL

The HTTP specification states that HTTP header names may be uppercase, lowercase, or mixed-case. Slim is smart enough to parse and return header values whether you request a header value using an upper, lower, or mixed case header name.

Request Cookies

Slim will automatically parse all HTTP Cookies sent with the current request. You can access Cookie values like this:

//Get all cookies
$allCookies = Slim::request()->cookies(); //returns array

//Get Cookie with name "foo"
$foo = Slim::request()->cookies('foo'); //returns string or array

Remember, only Cookies sent with the current HTTP request are accessible this way. If you set a cookie during the current request, it will not be accessible with this method until the subsequent request.

Back to Top

A Slim application also has a Response object that will ultimately be returned to the client after your application runs. The Response object contains three important features: the HTTP status code (ie. 200 OK), the response headers (ie. Content-Length), and the response body. Just as you access the Request object, you can also access the Response object:

$response = Slim::response();

Response Status

Change the Response status to change the type of response sent to the client. If you never touch the Response object, and if your code runs without issue, then the Response status will default to 200. If the Slim app cannot find a route to match the current request, the Response status will be 404. Or you can manually set the Response status with:

Slim::response()->status(200);

Pass in the numeric HTTP status code as a parameter. If you want to retrieve the current Response status, you can call the same method without passing in a parameter.

NOTE Normally, you won't manually set the Response status. There are other helper methods that will do this for you, such as `Slim::error()` (See [Error Handling](#errors)).

Response Headers

You can also add custom headers to the Response object:

Slim::response()->header('Content-Length', '200');

If you want to retrieve a header, you can call:

$length = Slim::response()->header('Content-Length');

Or if you want an array of all Response object headers:

Slim::response()->headers();

The Response headers are, for the most part, set automatically requiring no effort on your part. But just know that you can customize the Response object headers if you need to.

Response Body

Anything you echo() within a Route callback function will be appended to the Response body. It's that simple. If you need to manipulate the Response body in custom Middleware, you can call:

//Append the Response body
Slim::response()->write('More body content');

//Overwrite the Response body
Slim::response()->body('New body content');

Back to Top

Slim provides built-in support for HTTP caching. It is very simple to cache a resource using Slim::etag() or Slim::lastModified(). It is best to use one of these methods per route — not both. Both of these methods will instruct the browser client to cache the resource client-side. More details for each method are below. It is important that you call Slim::etag() or Slim::lastModified() in your route callback before any other code so that Slim can avoid unnecessary processing.

Slim provides built-in support for HTTP caching using ETags. An ETag is a unique identifier for a resource URL. When an ETag header is set with Slim::etag(), the browser client will send an If-None-Match header with each subsequent request for the same URL. If the ETag you define for the resource URL matches the If-None-Match request header, Slim will return a 304 Not Modified response which will prompt the browser client to use its cache; this also prevents Slim from serving the entire markup for the resource URL saving bandwidth and response times.

Setting an ETag with Slim is very simple. You only need to call Slim::etag() in your route callback, passing in a unique ID as the first and only argument.

Slim::get('/foo', function (){
	Slim::etag('unique-id');
	echo "This will be cached after the initial request!";
});

That's it. You only need to make sure the unique ETag ID is unique for the given route/resource. Also make sure the ETag unique ID changes as your route resource changes; otherwise, the browser client will continue serving its outdated cache.

Slim provides built-in support for HTTP caching using resource's last modified date. When you specify a last modified date, Slim tells the browser client the last date and time the current resource was modified. The browser client will then send a If-Modified-Since header with each subsequent request for the given resource URL. If the last modification date you specify matches the If-Modified-Since request header, Slim will return a 304 Not Modified response which will prompt the browser client to use its cache; this also prevents Slim from serving the entire markup for the resource URL saving bandwidth and response times.

Setting a last modified with Slim is very simple. You only need to call Slim::lastModified() in your route callback passing in a UNIX timestamp that represents the last modification date for the given route/resource. Be sure the Slim::lastModified() timestamp updates along with the route resource's last modification date; otherwise, the browser client will continue serving its outdated cache.

Slim::get('/foo', function (){
	Slim::lastModified(1286139652);
	echo "This will be cached after the initial request!";
});

Back to Top

Slim provides easy-to-use Cookie management with Slim::getCookie() and Slim::setCookie(). Slim also provides very secure encrypted Cookie management with Slim::setEncryptedCookie() and Slim::getEncryptedCookie().

Getting Normal Cookies

Assume a normal Cookie exists with name foo and value bar. This Cookie already exists in the web browser cache and is passed to the Slim application within the HTTP request. We can retrieve the Cookie value like this:

$value = Slim::getCookie('foo'); //$value === 'bar'

If you attempt to retrieve a Cookie that does not exist in the HTTP request, NULL is returned.

$value = Slim::getCookie('doesNotExist'); //$value === NULL

Getting Encrypted Cookies

Assume an encrypted Cookie exists with name foo and an value bar (before encryption). This Cookie already exists in the web browser cache and is passed to the Slim application within the HTTP request. We can retrieve the Cookie value like this:

$value = Slim::getEncryptedCookie('foo'); //$value === 'bar'

If you attempt to retrieve an encrypted Cookie that does not exist in the HTTP request, NULL is returned.

$value = Slim::getEncryptedCookie('doesNotExist'); //$value === NULL

Setting Normal Cookies

It is very easy to set a normal Cookie. This example sets a Cookie with name foo and value bar.

Slim::setCookie('foo', 'bar');

This assigns a new Cookie to the Response object that will be returned to the client in the HTTP response. The Cookie will be accessible to Slim::getCookie() in the subsequent HTTP request.

The default Cookie lifetime is 20 minutes. You can change the default lifetime by setting the cookie.lifetime value with Slim::init() as shown above in "Application Settings". Or, you can override the default expiration time like this:

//Cookie will expire one hour from now
Slim::setCookie('foo', 'bar', time() + 3600);

If the third argument is a string, it is converted to a UNIX timestamp with strtotime().

//Cookie will expire one hour from now
Slim::setCookie('foo', 'bar', '1 hour');

If the third argument is an integer and is 0, the cookie will expire when the visitor's session expires (usually when he closes his browser).

//Cookie will expire when session expires
Slim::setCookie('newCookie', 'newCookieValue', 0);

It is also possible to override other default Cookie values (see "Application Settings") like this:

//Cookie with all possible attributes
Slim::setCookie(
	'foo',              //name
	'bar',              //value
	'1 hour',           //expiration from now
	'/',                //path
	'joshlockhart.com',	//domain
	true,				//secure?
	true				//http only?
);

Setting Encrypted Cookies

It is very easy to set an encrypted Cookie. By default, Slim will encrypt your Cookies using AES-256 encryption. This example sets a Cookie with name foo and value bar.

Slim::setEncryptedCookie('foo', 'bar');

This assigns a new encrypted Cookie to the Response object that will be returned to the client in the HTTP response. The Cookie will be accessible to Slim::getEncryptedCookie() in the subsequent HTTP request.

The default Cookie lifetime is 20 minutes. You can change the default lifetime by setting the cookie.lifetime value with Slim::init() as shown above in "Application Settings". Or, you can override the default expiration time like this:

//Cookie will expire one hour from now
Slim::setEncryptedCookie('foo', 'bar', time() + 3600);

If the third argument is a string, it is converted to a UNIX timestamp with strtotime().

//Cookie will expire one hour from now
Slim::setEncryptedCookie('foo', 'bar', '1 hour');

If the third argument is an integer and is 0, the Cookie will expire when the visitor's session expires (usually when he closes his browser).

//Cookie will expire when session expires
Slim::setEncryptedCookie('foo', 'bar', 0);

It is also possible to override other default Cookie values (see "Application Settings") like this:

//Cookie with all possible attributes
Slim::setCookie(
	'foo',              //name
	'bar',              //value
	'1 hour',           //expiration from now
	'/',                //path
	'joshlockhart.com',	//domain
	true,				//secure?
	true				//http only?
);

Encrypted Cookie Settings

If you use encrypted Cookies, it is very important that you configure the Cookie secret key during application initialization. The secret key is known only to your application and is used to encrypt and decrypt Cookie values.

Slim::init(array(
    'cookies.secret_key' => 'Your app secret key'
));

For additional security, it is highly recommended that you configure the cookies.user_id setting after a user is authenticated by your application. This setting should be an identifier that uniquely identifies the authenticated user ensuring that any Cookies set for the current user are only valid for the current user and no one else. After user authentication, configure this setting like this:

Slim::config('cookies.user_id', THE_USER_ID);

If you are an advanced user, you may also change the encryption cipher, cipher mode, and other Cookie-related settings with Slim::init() or Slim::config(). See "Application Settings" above for these additional settings.

Configuring Cookies

See "Application Settings" above for Cookie-related application settings. Briefly, these settings are:

  • cookies.lifetime
  • cookies.path
  • cookies.domain
  • cookies.secure
  • cookies.httponly
  • cookies.secret_key
  • cookies.cipher
  • cookies.cipher_mode
  • cookies.encrypt
  • cookies.user_id

Back to Top

A View is a PHP class that returns a rendered template. You can use a View to render a template within a Route callback function.

//For PHP >= 5.3
Slim::get('/books/:id', function ($id) {
	Slim::render('myTemplate.php', array('id' => $id));
});

//For PHP < 5.3
Slim::get('/books/:id', 'show_book');
function show_book($id) {
	Slim::render('myTemplate.php', array('id' => $id));
}

If you need to pass data from the Route callback function to the View, you must explicitly do so by passing an array as the second parameter of Slim::render(), like this:

Slim::render(
	'myTemplate.php',
	array( 'name' => 'Josh' )
);

You can also set the Response status when you render a template:

Slim::render(
	'myTemplate.php',
	array( 'name' => 'Josh' ), 
	404
);

Slim's default View includes the requested template with require(). The included template will have access to any data passed by the Slim::render() method. Although this basic View works, it's not very powerful.

Templates Directory

By default, the built-in View class and all custom View classes will look for template files in the ./templates directory, relative to the bootstrap.php file. You can easily change the templates directory by setting the application templates setting with:

//During initialization
Slim::init(array('templates_dir' => '/path/to/templates'));

//Or, after initialization
Slim::config('templates_dir', '/path/to/templates');

Be sure you specify your custom templates directory during or immediately after application initialization. This setting will be available in your View class by calling:

$this->templatesDirectory();

Back to Top

A custom View is a PHP class that subclasses Slim_View and implements one method — render(). The custom View's render method is passed the name of the template as its one and only argument.

class CustomView extends Slim_View {
	public function render( $template ) {
		return 'The final rendered template';
	}
}

The custom View can do whatever it wants, so long as it ultimately returns the template's rendered output. A custom View makes it easy to integrate popular PHP templating systems, like Twig or Smarty.

The View class will have access to any data passed to it by the Slim::render() method. The View can access this data array with $this->data. Here is an example.

The Route

Slim::get('/books/:id', function ($id) {
	Slim::render('show.php', array('title' => 'Sahara'));
});

The View

class CustomView extends Slim_View {
	public function render( $template ) {
		//$template == 'show.php'
		//$this->data['title'] == 'Sahara'
	}
}

NOTE Use the `Slim::root()` method to find the absolute path to the Slim application's root directory. This can be helpful when resolving paths to template files!

To use your custom View, you must require the custom View class before you initialize Slim. Then you must tell Slim to use your custom View.

require 'slim/Slim.php';
require 'customView.php';
Slim::init(array('view' => 'CustomView'));

It is also possible to pass a custom View object instance into Slim::init, rather than just the name of the custom View class. This may be helpful if your custom View requires special preparation before application initialization.

Slim::init(array('view' => new CustomView()));

Back to Top

To pass data into a View for use in your templates, you can use the Slim::view()->setData() or Slim::view()->appendData() methods.

//Assign a single variable to the view
Slim::view()->setData('foo', 'bar');

//Set the View data to an array;
//Overwrites existing data;
Slim::view()->setData(array('foo' => 'bar', 'one' => 1));

//Append View data with associative array;
//Merges new data with existing data;
Slim::view()->appendData(array('foo' => 'bar'));

Back to Top

Slim provides a hook plugin architecture, allowing you to register callable objects to be invoked at specific moments in the Slim application lifecycle. All hooks may access and interact with the Request, Response, Router, and View objects.

Plugins are only available in the DEVELOP branch until version 1.1 is officially released

Plugin Hooks

The available hooks within a Slim application are:

slim.before

This hook is invoked before the Slim application is run and before output buffering is turned on. This hook is invoked once during the Slim application lifecycle.

slim.before.router

This hook is invoked after output buffering is turned on and before the router is dispatched. This hook is invoked once during the Slim application lifecycle.

slim.before.dispatch

This hook is invoked before the current matching route is dispatched. Usually this hook is invoked only once during the Slim application lifecycle; however, this hook may be invoked multiple times if a matching route chooses to pass to a subsequent matching route.

slim.after.dispatch

This hook is invoked after the current matching route is dispatched. Usually this hook is invoked only once during the Slim application lifecycle; however, this hook may be invoked multiple times if a matching route chooses to pass to a subsequent matching route.

slim.after.router

This hook is invoked after the router is dispatched, before the Response is sent to the client, and before output buffering is turned off. This hook is invoked once during the Slim application lifecycle.

slim.after

This hook is invoked after output buffering is turned off and after the Response is sent to the client. This hook is invoked once during the Slim application lifecycle.

Registering a callable object for a hook

To register a callable object for a given hook:

Slim::hook('slim.before.dispatch', function () {
	echo 'Prepare to dispatch!';
});

The first argument is the hook name, and the second argument is a callable object (ie. an anonymous function, a function name, or an array whose elements specify a class/object and method to call).

Each hook maintains an array of registered objects. When the hook is invoked, each of its registered objects is called in the order registered.

Creating new hooks

You may create new hooks to be invoked within the context of your own plugin. To create a new hook, insert the following code within your plugin. This code will call all objects registered for the specified hook name.

Slim::hook('my.new.hook.name');

The first and only argument should be the name of your new hook. Nothing prevents you from overwriting an existing hook, so it is recommended that you namespace your hooks with a unique prefix:

Slim::hook('myplugin.new.hook.name');

Distributing plugins

A plugin should adhere to this directory structure:

thePluginName/
	README
	ThePluginName.php
	lib/

A plugin should have its own directory, a README file, and a primary PHP script. The README file should provide, at minimum, the following information:

  • Plugin name
  • Plugin version
  • Plugin URL
  • Plugin author
  • Plugin description
  • Plugin usage

The primary PHP script, "ThePluginName.php" in the example above, should do all that is required to initialize and register the plugin with a Slim application. If a plugin has more than one PHP script, place other PHP scripts inside of a lib/ directory.

If a plugin requires more advanced setup, provide detailed instructions for doing so in the plugin's README file.

Installing plugins

To "install" a Slim plugin, you only need to require the plugin's primary PHP script into your Slim application's bootstrap.php file. It is important that you require plugin files after the Slim application has been initialized.

require 'slim/Slim.php';
Slim::init();
require 'plugins/thePluginName/ThePluginName.php';

Example Plugins

Authentication

This is a very basic example, but it demonstrates how you may approach authentication within your Slim application.

<?php
/**
 * MyPlugin.php
 */
Slim::hook('slim.before.dispatch', function () {
	$request = Slim::request();
	$currentRoute = Slim::router()->current();
	if ( preg_match('@^users/@', $currentRoute->pattern) ) {
		//Authenticate current user or redirect to login page
	}
});
?>

Appending new routes

This example appends routes to an existing Slim application. This demonstrates how you can package routes and other complex functionality into a single plugin and easily integrate it within an existing Slim application.

<?php
/**
 * MyPlugin.php
 */
Slim::hook('slim.before', function () {
	Slim::get('/login', function () {
		//Render login form
	});
	Slim::post('/login', function () {
		//Log in user
	});
});
?>

The Slim PHP 5 framework includes a Slim_Log class that sends messages of varying importance to a specific output. Use the following static methods provided by the Slim_Log class to log objects in a Slim PHP 5 application.

Slim_Log::debug($var);

Slim_Log::info($var);

Slim_Log::warn($var);

Slim_Log::error($var);

Slim_Log::fatal($var);

Logging is disabled by default. Enable logging during Slim application initialization like this:

Slim::init(array(
	'log.enable' => true
));

By default, assuming logging is enabled, Slim will use a default Logger that writes a unique log file per day to a user-defined filesystem directory.

Log Directory

If using the default Logger, you must specify the relative or absolute path to the log files directory, and this directory must be writable by PHP.

Slim::init(array(
	'log.enable' => true,
	'log.path' => '../path/to/logs'
));

Log Level

The default Logger also allows you to filter which messages are written to the log file by importance, measured from 0 (most important) to 4 (least important):

Fatal (0) > Error (1) > Warn (2) > Info (3) > Debug (4)

If you tell Slim to log messages at level 4, Slim will log all messages. If you tell Slim to log messages at level 2, Slim will log Warn, Error, and Fatal messages. And so on. Define the logger level like this:

Slim::init(array(
	'log.enable' => true,
	'log.path' => '../path/to/logs',
	'log.level' => 3
));

You can provide a custom Logger to log objects to a database, to stdOut, to stdErr, to Twitter, to IRC, or to anywhere you see fit. The Slim_Log class mentioned above is merely an adapter and delegates the actual logging to a Logger object. The Logger object must implement this interface:

public function debug( mixed $var );
public function info( mixed $var );
public function warn( mixed $var );
public function error( mixed $var );
public function fatal( mixed $var );

In this example, $var may be any data type; it is the responsibility of the Logger object to log the variable appropriately.

Declare your custom Logger object during Slim application initialization like this:

Slim::init(array(
	'log.enable' => true,
	'log.logger' => new MyCustomLogger()
));

If you use a custom Logger, you may ignore the application settings log.path and log.level.

Back to Top

Let's face it: sometimes things go wrong. But it is important that you intercept errors and respond to them appropriately. Slim provides several helper methods to help you respond to errors.

A common method used to respond to errors is Slim::halt(). This method accepts two parameters: the HTTP status code and an optional message.

//Send a default 500 error response
Slim::halt(500);

//Send a 403 Forbidden response
Slim::halt(403, 'You shall not pass');

This method will override the current Response body and Response status code, and then immediately send the new Response to the client. If you would like to render a template to display error messages, you should instead call:

Slim::render(
	'errorTemplate.php',
	array( 'error' => 'Permission Denied'),
	403
);

Slim::halt() may send any type of Response to the client: informational, success, redirect, not found, client error, or server error.

This method allows you to specify a custom error handler that will be invoked when an error or exception occurs and debugging is disabled (if debugging is enabled, a developer-oriented error message will appear instead). This handler should ideally render a visitor-friendly page that explains an error occurred. Similar to Slim::notFound(), this method acts as both a getter and a setter.

Setting the Error handler

//PHP 5 >= 5.3
Slim::error(function () {
	Slim::render('error.php');
});

//PHP 5 < 5.3
Slim::error('custom_error_handler');
function custom_error_handler(){
	Slim::render('error.php');
}

Invoking the Error handler

Slim will automatically invoke your error handler if an error or exception occurs and debugging is disabled. You can also directly invoke this method yourself by calling Slim::error() directly in your code.

Debugging

Using Slim::config(), you can enable or disable application debugging like this:

//Enable debugging (on by default)
Slim::config('debug', true);

//Disable debugging
Slim::config('debug', false);

If debugging is enabled, a detailed error screen will appear with the error message, the affected file, the file line number, and a stack trace. If debugging is disabled, your custom Error handler will be invoked instead (see above).

Slim::stop()

This method does what it says. It immediately stops the Slim application and sends the response as-is to the client. No ifs, ands, or buts.

Back to Top

Clone this wiki locally