8000 [HttpFoundation] Add documentation about the session. · Pull Request #1154 · symfony/symfony-docs · GitHub
[go: up one dir, main page]

Skip to content

[HttpFoundation] Add documentation about the session. #1154

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from Mar 19, 2012
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
[HttpFoundation] Add documentation about the session.
  • Loading branch information
Drak committed Mar 14, 2012
commit f8e9fc33a1cd80dfa04cdb5e35337a6ec2d400f6
229 changes: 227 additions & 2 deletions components/http_foundation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -378,5 +378,230 @@ abstracts the hard work behind a simple API::
Session
-------

TBD -- This part has not been written yet as it will probably be refactored
soon in Symfony 2.1.
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.

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 and retrieve flash messages
$session->getFlashBag()->set('notice', 'Profile updated');

echo $session->getFlashBag()->get('notice');

Save Handlers
~~~~~~~~~~~~~

The PHP session workflow has 6 possible operations that may occur. The normal
session follows `open`, `read`, `write` and `close`, with the possibility of
`destroy` and `gc` (garbage collection which will expire any old sessions: `gc`
is called randomly according to PHP's configuration and if called, it is invoked
after the `open` operation). You can read more about this at
http://php.net/session.customhandler

Native PHP Save Handlers
~~~~~~~~~~~~~~~~~~~~~~~~

So-called 'native' handlers are session handlers are either compiled into PHP or
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mising that

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary here since this is a direct statement of what native handlers are.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So-called 'native' handlers are session handlers are

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

provided by PHP extensions, such as PHP-Sqlite, PHP-Memcached and so on. The
handlers are compiled and can be activated directly in PHP using
`ini_set('session.save_handler', $name);` and are usually configured with
`ini_set('session.save_path', $path);` and sometimes, a variety of other PHP
`ini` directives.

Symfony2 provides drivers for native handlers which are easy to configure, these are:

* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler`
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeSqliteSessionHandler`
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeMemcacheSessionHandler`
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeMemcachedSessionHandler`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should use the :class: syntax to link to the api doc (for all appropriate places)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.


Example of use:

use Symfony\\Component\\HttpFoundation\\Session\\Session;
use Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage;
use Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeMemcachedSessionHandler;

$storage = new NativeSessionStorage(array(), new NativeMemcachedSessionHandler());
$session = new Session($storage);

Custom Save Handlers
~~~~~~~~~~~~~~~~~~~~

Custom handlers are those which completely replace PHP's built in session save
handlers by providing six callback functions which PHP calls internally at
various points in the session workflow.

Symfony2 HttpFoudation provides some by default and these can easily serve as
examples if you wish to write your own.

* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler`
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcacheSessionHandler`
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcachedSessionHandler`
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NullSessionHandler`

Example:

use Symfony\\Component\\HttpFoundation\\Session\\Session;
use Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorage;
use Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler;

$storage = new NativeSessionStorage(array(), new PdoSessionHandler());
$session = new Session($storage);

Session Bags
------------

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 like 'attributes' or 'flash messages'.

This approach also mitigates namespace pollution within the `$_SESSION`
super-global because each bag stores all it's data under a unique namespace.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

corrected

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 bags, with two separate implementations.
Everything is written against interfaces so you may extend or create your own
bag types if necessary.

Attributes
~~~~~~~~~~

The purpose of the bags implementing the `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.

* `AttributeBag` - this is the standard default implementation.
* `NamespacedAttributeBag` - this implementation allows for attributes to be
stored in a structured namespace.

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('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 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.

Flash messages
~~~~~~~~~~~~~~

The purpose of the `FlashBagInterface` is to provide a way of settings and
retrieving messages on a per session basis. The usual workflow for flash
messages would be set in an request, and displayed on 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 a
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.

* `AutoExpireFlashBag` - This implementation messages set in one page-load will
be available for display only on the next page load. These messages will auto
expire regardless of if they are retrieved or not.
* `FlashBag` - In this implementation, messages will remain in the session until
they are explicitly retrieved or cleared. This makes it possible to use ESI
caching.

Testability
-----------

Symfony2 is designed from the ground up with code-testability in mind. In order
to make your code which utilises session easily testable we provide two separate
mock storage mechanisms for both unit testing and functional testing.

Testing code using real sessions is trick because PHP's workflow state is global
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tricky

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

corrected

and it is not possible to have multiple concurrent sessions in the same PHP
process.

The mock storage engines simulate the PHP session workflow without actually
starting one allowing you to test your code without complications. You may also
run multiple instances in the same PHP process.

The only caveat, `session_id()` is global, so the session ID should be read
using `$session->getId()` but generally this is of no relevance during testing.

Unit Testing
~~~~~~~~~~~~

For unit testing where it is not necessary to persist the session, you should
simply swap out the default storage engine with
`Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockArraySessionStorage`.

use Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockArraySessionStorage;
use Symfony\\Component\\HttpFoundation\\Session\\Session;

$session = new Session(new MockArraySessionStorage());

Functional Testing
~~~~~~~~~~~~~~~~~~

For functional testing where you may need to persist session data across
separate PHP processes, simply change the storage engine to
`Symfony\\Component\\HttpFoundation\\SessionMockFileSessionStorage`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong FQCN

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.


use Symfony\\Component\\HttpFoundation\\Session\\Session;
use Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockFileessionStorage;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing S

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


$session = new Session(new MockFileSessionStorage());

PHP 5.4 compatibility
~~~~~~~~~~~~~~~~~~~~~

Since PHP 5.4.0, `\SessionHandler` and `\SessionHandlerInterface` are available.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should use :phpclass:SessionHandler`` so that it links to the PHP doc

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! changed.

Symfony 2.1 provides forward compatibility for the `\SessionHandlerInterface` so
it can be used under PHP 5.3. This greatly improves inter-operability with other
libraries.

`\SessionHandler` is a special PHP internal class which exposes native save
handlers to PHP user-space. You can read more about it at
http://php.net/sessionhandler.

In order to provide a solution for those using PHP 5.4, Symfony2 has a special
class called `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeSessionHandler`
which under PHP 5.4, extends from `\SessionHandler` and under PHP 5.3 is just a
empty base class. This provides some interesting opportunities to leverage
PHP 5.4 functionality if it is available.

Handler Proxy
~~~~~~~~~~~~~

`SessionStorage` injects storage handlers into a handler proxy. The reason for
this is that under PHP 5.4, all handlers implement `\SessionHandlerInterface`
including native handlers (those which activate internal PHP/PHP-extension
handlers. Native handlers under PHP 5.4 will be children of
`\SessionHandler` which allows one to intercept and modify even native session
handlers.

In order to manage all of this, Symfony2 uses a proxy handler object. It means
that you could write a single adapter, that for example encrypts the session
data, and it will work regardless of the save handler in use, custom, or native.
0