-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
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` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you should use the There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wrong FQCN There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing S There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you should use There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mising
that
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed