Skip to content

Latest commit

 

History

History
328 lines (233 loc) · 13.5 KB

sessions.rst

File metadata and controls

328 lines (233 loc) · 13.5 KB
.. index::
   single: HTTP
   single: HttpFoundation, Sessions

Session Management

The Symfony2 HttpFoundation Component has a very powerful and flexible session subsystem which is designed to provide session management through a simple object-oriented interface using a variety of session storage drivers.

Sessions are used via the simple :class:`Symfony\\Component\\HttpFoundation\\Session\\Session` implementation of :class:`Symfony\\Component\\HttpFoundation\\Session\\SessionInterface` interface.

Quick example:

use Symfony\Component\HttpFoundation\Session\Session;

$session = new Session();
$session->start();

// set and get session attributes
$session->set('name', 'Drak');
$session->get('name');

// set flash messages
$session->getFlashBag()->add('notice', 'Profile updated');

// retrieve messages
foreach ($session->getFlashBag()->get('notice', array()) as $message) {
    echo "<div class='flash-notice'>$message</div>";
}

Note

Symfony sessions are designed to replace several native PHP functions. Applications should avoid using session_start(), session_regenerate_id(), session_id(), session_name(), and session_destroy() and instead use the APIs in the following section.

Note

While it is recommended to explicitly start a session, a sessions will actually start on demand, that is, if any session request is made to read/write session data.

Caution!

Symfony sessions are incompatible with PHP ini directive session.auto_start = 1 This directive should be turned off in php.ini, in the webserver directives or in .htaccess.

Session API

The :class:`Symfony\\Component\\HttpFoundation\\Session\\Session` class implements :class:`Symfony\\Component\\HttpFoundation\\Session\\SessionInterface`.

The :class:`Symfony\\Component\\HttpFoundation\\Session\\Session` has a simple API as follows divided into a couple of groups.

Session workflow

Session attributes

The attributes are stored internally in an "Bag", a PHP object that acts like an array. A few methods exist for "Bag" management:

Session meta-data

Session Data Management

PHP's session management requires the use of the $_SESSION super-global, however, this interferes somewhat with code testability and encapsulation in a OOP paradigm. To help overcome this, Symfony2 uses 'session bags' linked to the session to encapsulate a specific dataset of 'attributes' or 'flash messages'.

This approach also mitigates namespace pollution within the $_SESSION super-global because each bag stores all its data under a unique namespace. This allows Symfony2 to peacefully co-exist with other applications or libraries that might use the $_SESSION super-global and all data remains completely compatible with Symfony2's session management.

Symfony2 provides 2 kinds of storage bags, with two separate implementations. Everything is written against interfaces so you may extend or create your own bag types if necessary.

:class:`Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface` has the following API which is intended mainly for internal purposes:

Attributes

The purpose of the bags implementing the :class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface` is to handle session attribute storage. This might include things like user ID, and remember me login settings or other user based state information.

Any plain key => value storage system is limited in the extent to which complex data can be stored since each key must be unique. You can achieve namespacing by introducing a naming convention to the keys so different parts of your application could operate without clashing. For example, module1.foo and module2.foo. However, sometimes this is not very practical when the attributes data is an array, for example a set of tokens. In this case, managing the array becomes a burden because you have to retrieve the array then process it and store it again:

$tokens = array('tokens' => array('a' => 'a6c1e0b6',
                                  'b' => 'f4a7b1f3'));

So any processing of this might quickly get ugly, even simply adding a token to the array:

$tokens = $session->get('tokens');
$tokens['c'] = $value;
$session->set('tokens', $tokens);

With structured namespacing, the key can be translated to the array structure like this using a namespace character (defaults to /):

$session->set('tokens/c', $value);

This way you can easily access a key within the stored array directly and easily.

:class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface` has a simple API

Flash messages

The purpose of the :class:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface` is to provide a way of setting and retrieving messages on a per session basis. The usual workflow for flash messages would be set in an request, and displayed after a page redirect. For example, a user submits a form which hits an update controller, and after processing the controller redirects the page to either the updated page or an error page. Flash messages set in the previous page request would be displayed immediately on the subsequent page load for that session. This is however just one application for flash messages.

:class:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface` has a simple API

For simple applications it is usually sufficient to have one flash message per type, for example a confirmation notice after a form is submitted. However, flash messages are stored in a keyed array by flash $type which means your application can issue multiple messages for a given type. This allows the API to be used for more complex messaging in your application.

Examples of setting multiple flashes:

use Symfony\Component\HttpFoundation\Session\Session;

$session = new Session();
$session->start();

// add flash messages
$session->getFlashBag()->add(
    'warning',
    'Your config file is writable, it should be set read-only'
);
$session->getFlashBag()->add('error', 'Failed to update name');
$session->getFlashBag()->add('error', 'Another error');

Displaying the flash messages might look like this:

Simple, display one type of message:

// display warnings
foreach ($session->getFlashBag()->get('warning', array()) as $message) {
    echo "<div class='flash-warning'>$message</div>";
}

// display errors
foreach ($session->getFlashBag()->get('error', array()) as $message) {
    echo "<div class='flash-error'>$message</div>";
}

Compact method to process display all flashes at once:

foreach ($session->getFlashBag()->all() as $type => $messages) {
    foreach ($messages as $message) {
        echo "<div class='flash-$type'>$message</div>\n";
    }
}