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

Skip to content

Commit f8e9fc3

Browse files
author
Drak
committed
[HttpFoundation] Add documentation about the session.
1 parent d04b06d commit f8e9fc3

File tree

1 file changed

+227
-2
lines changed

1 file changed

+227
-2
lines changed

components/http_foundation.rst

Lines changed: 227 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,5 +378,230 @@ abstracts the hard work behind a simple API::
378378
Session
379379
-------
380380

381-
TBD -- This part has not been written yet as it will probably be refactored
382-
soon in Symfony 2.1.
381+
The Symfony2 HttpFoundation Component has a very powerful and flexible session
382+
subsystem which is designed to provide session management through a simple
383+
object-oriented interface using a variety of session storage drivers.
384+
385+
Quick example:
386+
387+
use Symfony\\Component\\HttpFoundation\\Session\\Session;
388+
389+
$session = new Session();
390+
$session->start();
391+
392+
// set and get session attributes
393+
$session->set('name', 'Drak');
394+
$session->get('name');
395+
396+
// set and retrieve flash messages
397+
$session->getFlashBag()->set('notice', 'Profile updated');
398+
399+
echo $session->getFlashBag()->get('notice');
400+
401+
Save Handlers
402+
~~~~~~~~~~~~~
403+
404+
The PHP session workflow has 6 possible operations that may occur. The normal
405+
session follows `open`, `read`, `write` and `close`, with the possibility of
406+
`destroy` and `gc` (garbage collection which will expire any old sessions: `gc`
407+
is called randomly according to PHP's configuration and if called, it is invoked
408+
after the `open` operation). You can read more about this at
409+
http://php.net/session.customhandler
410+
411+
Native PHP Save Handlers
412+
~~~~~~~~~~~~~~~~~~~~~~~~
413+
414+
So-called 'native' handlers are session handlers are either compiled into PHP or
415+
provided by PHP extensions, such as PHP-Sqlite, PHP-Memcached and so on. The
416+
handlers are compiled and can be activated directly in PHP using
417+
`ini_set('session.save_handler', $name);` and are usually configured with
418+
`ini_set('session.save_path', $path);` and sometimes, a variety of other PHP
419+
`ini` directives.
420+
421+
Symfony2 provides drivers for native handlers which are easy to configure, these are:
422+
423+
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler`
424+
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeSqliteSessionHandler`
425+
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeMemcacheSessionHandler`
426+
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeMemcachedSessionHandler`
427+
428+
Example of use:
429+
430+
use Symfony\\Component\\HttpFoundation\\Session\\Session;
431+
use Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage;
432+
use Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeMemcachedSessionHandler;
433+
434+
$storage = new NativeSessionStorage(array(), new NativeMemcachedSessionHandler());
435+
$session = new Session($storage);
436+
437+
Custom Save Handlers
438+
~~~~~~~~~~~~~~~~~~~~
439+
440+
Custom handlers are those which completely replace PHP's built in session save
441+
handlers by providing six callback functions which PHP calls internally at
442+
various points in the session workflow.
443+
444+
Symfony2 HttpFoudation provides some by default and these can easily serve as
445+
examples if you wish to write your own.
446+
447+
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler`
448+
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcacheSessionHandler`
449+
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcachedSessionHandler`
450+
* `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NullSessionHandler`
451+
452+
Example:
453+
454+
use Symfony\\Component\\HttpFoundation\\Session\\Session;
455+
use Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorage;
456+
use Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler;
457+
458+
$storage = new NativeSessionStorage(array(), new PdoSessionHandler());
459+
$session = new Session($storage);
460+
461+
Session Bags
462+
------------
463+
464+
PHP's session management requires the use of the `$_SESSION` super-global,
465+
however, this interferes somewhat with code testability and encapsulation in a
466+
OOP paradigm. To help overcome this Symfony2 uses 'session bags' linked to the
467+
session to encapsulate a specific dataset like 'attributes' or 'flash messages'.
468+
469+
This approach also mitigates namespace pollution within the `$_SESSION`
470+
super-global because each bag stores all it's data under a unique namespace.
471+
This allows Symfony2 to peacefully co-exist with other applications or libraries
472+
that might use the `$_SESSION` super-global and all data remains completely
473+
compatible with Symfony2's session management.
474+
475+
Symfony2 provides 2 kinds of bags, with two separate implementations.
476+
Everything is written against interfaces so you may extend or create your own
477+
bag types if necessary.
478+
479+
Attributes
480+
~~~~~~~~~~
481+
482+
The purpose of the bags implementing the `AttributeBagInterface` is to handle
483+
session attribute storage. This might include things like user ID, and remember
484+
me login settings or other user based state information.
485+
486+
* `AttributeBag` - this is the standard default implementation.
487+
* `NamespacedAttributeBag` - this implementation allows for attributes to be
488+
stored in a structured namespace.
489+
490+
Any plain `key => value` storage system is limited in the extent to which
491+
complex data can be stored since each key must be unique. You can achieve
492+
namespacing by introducing a naming convention to the keys so different parts of
493+
your application could operate without clashing. For example, `module1.foo` and
494+
`module2.foo`. However, sometimes this is not very practical when the attributes
495+
data is an array, for example a set of tokens. In this case, managing the array
496+
becomes a burden because you have to retrieve the array then process it and
497+
store it again.
498+
499+
'tokens' => array('a' => 'a6c1e0b6',
500+
'b' => 'f4a7b1f3')
501+
502+
So any processing of this might quickly get ugly, even simply adding a token to
503+
the array:
504+
505+
$tokens = $session->get('tokens');
506+
$tokens['c'] = $value;
507+
$session->set('tokens', $tokens);
508+
509+
With structured namespacing, the the key can be translated to the array
510+
structure like this using a namespace character (defaults to `/`).
511+
512+
$session->set('tokens/c', $value);
513+
514+
This way you can easily access a key within the stored array directly and easily.
515+
516+
Flash messages
517+
~~~~~~~~~~~~~~
518+
519+
The purpose of the `FlashBagInterface` is to provide a way of settings and
520+
retrieving messages on a per session basis. The usual workflow for flash
521+
messages would be set in an request, and displayed on page redirect. For
522+
example, a user submits a form which hits an update controller, and after
523+
processing the controller redirects the page to either the updated page or a
524+
error page. Flash messages set in the previous page request would be displayed
525+
immediately on the subsequent page load for that session. This is however just
526+
one application for flash messages.
527+
528+
* `AutoExpireFlashBag` - This implementation messages set in one page-load will
529+
be available for display only on the next page load. These messages will auto
530+
expire regardless of if they are retrieved or not.
531+
* `FlashBag` - In this implementation, messages will remain in the session until
532+
they are explicitly retrieved or cleared. This makes it possible to use ESI
533+
caching.
534+
535+
Testability
536+
-----------
537+
538+
Symfony2 is designed from the ground up with code-testability in mind. In order
539+
to make your code which utilises session easily testable we provide two separate
540+
mock storage mechanisms for both unit testing and functional testing.
541+
542+
Testing code using real sessions is trick because PHP's workflow state is global
543+
and it is not possible to have multiple concurrent sessions in the same PHP
544+
process.
545+
546+
The mock storage engines simulate the PHP session workflow without actually
547+
starting one allowing you to test your code without complications. You may also
548+
run multiple instances in the same PHP process.
549+
550+
The only caveat, `session_id()` is global, so the session ID should be read
551+
using `$session->getId()` but generally this is of no relevance during testing.
552+
553+
Unit Testing
554+
~~~~~~~~~~~~
555+
556+
For unit testing where it is not necessary to persist the session, you should
557+
simply swap out the default storage engine with
558+
`Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockArraySessionStorage`.
559+
560+
use Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockArraySessionStorage;
561+
use Symfony\\Component\\HttpFoundation\\Session\\Session;
562+
563+
$session = new Session(new MockArraySessionStorage());
564+
565+
Functional Testing
566+
~~~~~~~~~~~~~~~~~~
567+
568+
For functional testing where you may need to persist session data across
569+
separate PHP processes, simply change the storage engine to
570+
`Symfony\\Component\\HttpFoundation\\SessionMockFileSessionStorage`.
571+
572+
use Symfony\\Component\\HttpFoundation\\Session\\Session;
573+
use Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockFileessionStorage;
574+
575+
$session = new Session(new MockFileSessionStorage());
576+
577+
PHP 5.4 compatibility
578+
~~~~~~~~~~~~~~~~~~~~~
579+
580+
Since PHP 5.4.0, `\SessionHandler` and `\SessionHandlerInterface` are available.
581+
Symfony 2.1 provides forward compatibility for the `\SessionHandlerInterface` so
582+
it can be used under PHP 5.3. This greatly improves inter-operability with other
583+
libraries.
584+
585+
`\SessionHandler` is a special PHP internal class which exposes native save
586+
handlers to PHP user-space. You can read more about it at
587+
http://php.net/sessionhandler.
588+
589+
In order to provide a solution for those using PHP 5.4, Symfony2 has a special
590+
class called `Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeSessionHandler`
591+
which under PHP 5.4, extends from `\SessionHandler` and under PHP 5.3 is just a
592+
empty base class. This provides some interesting opportunities to leverage
593+
PHP 5.4 functionality if it is available.
594+
595+
Handler Proxy
596+
~~~~~~~~~~~~~
597+
598+
`SessionStorage` injects storage handlers into a handler proxy. The reason for
599+
this is that under PHP 5.4, all handlers implement `\SessionHandlerInterface`
600+
including native handlers (those which activate internal PHP/PHP-extension
601+
handlers. Native handlers under PHP 5.4 will be children of
602+
`\SessionHandler` which allows one to intercept and modify even native session
603+
handlers.
604+
605+
In order to manage all of this, Symfony2 uses a proxy handler object. It means
606+
that you could write a single adapter, that for example encrypts the session
607+
data, and it will work regardless of the save handler in use, custom, or native.

0 commit comments

Comments
 (0)
0