-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Slim Framework Documentation
- Overview
- System Requirements
- Initialize Slim NEW
- RESTful Routes
- The Request Object
- The Response Object
- HTTP Caching
- Cookies NEW
- Views NEW
- Plugins
- Logging NEW
- Error Handling
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
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';
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.
To configure your Slim application, pass an associative array into the Slim::init()
method. The available settings are:
Enable or disable application logging.
- Data Type
- boolean
- Default
- false
Relative or absolute path to log files directory. Directory must be writable by PHP.
- Data Type
- string
- Default
- ./logs
An instance of a custom logger class that implements the requried interface described in the Custom Logger section below. Only necessary if using a custom logger class. This setting is only applicable if using the default Slim logger.
- Data Type
- Object
- Default
- null
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
- Object
- Default
- null
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
Relative or absolute filesystem path to template files directory used by the application View.
- Data Type
- string
- Default
- ./templates
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
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
Determines the default browser Cookie path if none specified with Slim::setCookie
or Slim::setEncryptedCookie
.
- Data Type
- string
- Default
- /
Determies the default browser Cookie domain if none specified with Slim::setCookie
or Slim::setEncryptedCookie
.
- Data Type
- string
- Default
- null
Should the Slim application transfer Cookies over SSL/HTTPS only?
- Data Type
- boolean
- Default
- false
Should the Slim application transfer Cookies using the HTTP protocol only?
- Data Type
- boolean
- Default
- false
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
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
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
Should Slim::setEncryptedCookie()
encrypt browser Cookie values?
- Data Type
- boolean
- Default
- true
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()
.
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'
));
$settingValue = Slim::config('foo'); //returns 'bar'
If the requested setting does not exist, Slim::config()
returns NULL
instead.
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.
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.
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.
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>
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>
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.
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.
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.
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:
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 Route::setDefaultConditions()
. If for whatever reason you need to get the application-wide default conditions, you can fetch them with 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,}'));
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+'));
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.
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();
});
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.
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.
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');
}
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";
}
});
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.
A Slim application has a Request object that provides details about the current HTTP request. This Request object determines how your Slim application will run: it provides the HTTP request method and the HTTP request URI among other things. To access the Request object, you can call:
$request = Slim::request();
NOTE You will typically use the Request object inside a Route's callback function.
An HTTP request may have associated parameters (not to be confused with Route parameters above). To access the request parameters, you can call the Request object 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
rather than throwing an error. 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();
The Request object can tell you more about the HTTP request.
//Get the request URI
$uri = Slim::request()->resource;
//Get the request method: GET, POST, PUT, or DELETE
$method = Slim::request()->method;
//Is this an AJAX request?
$isAjax = Slim::request()->isAjax;
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();
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)).
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.
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');
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!";
});
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()
.
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
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
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?
);
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?
);
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.
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
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.
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:
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();
A custom View is a PHP class that extends 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 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.
Slim::get('/books/:id', function ($id) {
Slim::render('show.php', array('title' => 'Sahara'));
});
class CustomView extends 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()));
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'));
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
The available hooks within a Slim application are:
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.
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.
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.
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.
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.
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.
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.
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');
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.
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';
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
}
});
?>
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 Log
class that sends messages of varying importance to a specific output. Use the following static methods provided by the Log
class to log objects in a Slim PHP 5 application.
Log::debug($var);
Log::info($var);
Log::warn($var);
Log::error($var);
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.
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'
));
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 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 $object );
public function info( mixed $object );
public function warn( mixed $object );
public function error( mixed $object );
public function fatal( mixed $object );
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
.
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.
//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');
}
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.
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).
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.