From f8e9fc33a1cd80dfa04cdb5e35337a6ec2d400f6 Mon Sep 17 00:00:00 2001 From: Drak Date: Fri, 9 Mar 2012 16:53:22 +0545 Subject: [PATCH 1/3] [HttpFoundation] Add documentation about the session. --- components/http_foundation.rst | 229 ++++++++++++++++++++++++++++++++- 1 file changed, 227 insertions(+), 2 deletions(-) diff --git a/components/http_foundation.rst b/components/http_foundation.rst index a12bc3a37f7..2d0fa37b03e 100644 --- a/components/http_foundation.rst +++ b/components/http_foundation.rst @@ -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` + +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. +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 +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`. + + use Symfony\\Component\\HttpFoundation\\Session\\Session; + use Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockFileessionStorage; + + $session = new Session(new MockFileSessionStorage()); + +PHP 5.4 compatibility +~~~~~~~~~~~~~~~~~~~~~ + +Since PHP 5.4.0, `\SessionHandler` and `\SessionHandlerInterface` are available. +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. \ No newline at end of file From 66ce132eba393fe0aa3c89771853097eb980ec37 Mon Sep 17 00:00:00 2001 From: Drak Date: Thu, 15 Mar 2012 00:15:18 +0545 Subject: [PATCH 2/3] Corrections --- components/http_foundation.rst | 101 ++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/components/http_foundation.rst b/components/http_foundation.rst index 2d0fa37b03e..b4433a5b763 100644 --- a/components/http_foundation.rst +++ b/components/http_foundation.rst @@ -382,7 +382,10 @@ 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: +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; @@ -408,24 +411,25 @@ 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 +So-called 'native' handlers, are session handlers which 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` + * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeFileSessionHandler`; + * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeSqliteSessionHandler`; + * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeMemcacheSessionHandler`; + * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeMemcachedSessionHandler`; -Example of use: +Example of use:: use Symfony\\Component\\HttpFoundation\\Session\\Session; use Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage; @@ -444,12 +448,12 @@ 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` + * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler`; + * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcacheSessionHandler`; + * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcachedSessionHandler`; + * :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NullSessionHandler`; -Example: +Example:: use Symfony\\Component\\HttpFoundation\\Session\\Session; use Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorage; @@ -467,7 +471,7 @@ 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. +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. @@ -479,13 +483,14 @@ 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. +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. -* `AttributeBag` - this is the standard default implementation. -* `NamespacedAttributeBag` - this implementation allows for attributes to be - stored in a structured namespace. +* :class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBag` + This is the standard default implementation. +* :class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\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 @@ -500,14 +505,14 @@ store it again. 'b' => 'f4a7b1f3') So any processing of this might quickly get ugly, even simply adding a token to -the array: +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 `/`). +structure like this using a namespace character (defaults to `/`):: $session->set('tokens/c', $value); @@ -516,19 +521,21 @@ 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 +The purpose of the :class:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\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. + +* :class:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\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 +* :class:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\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. @@ -539,7 +546,7 @@ 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 +Testing code using real sessions is tricky because PHP's workflow state is global and it is not possible to have multiple concurrent sessions in the same PHP process. @@ -555,7 +562,7 @@ 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`. +:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockArraySessionStorage`:: use Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockArraySessionStorage; use Symfony\\Component\\HttpFoundation\\Session\\Session; @@ -567,27 +574,26 @@ 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`. +:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockFileSessionStorage`:: use Symfony\\Component\\HttpFoundation\\Session\\Session; - use Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockFileessionStorage; + use Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockFileSessionStorage; $session = new Session(new MockFileSessionStorage()); PHP 5.4 compatibility ~~~~~~~~~~~~~~~~~~~~~ -Since PHP 5.4.0, `\SessionHandler` and `\SessionHandlerInterface` are available. -Symfony 2.1 provides forward compatibility for the `\SessionHandlerInterface` so +Since PHP 5.4.0, :phpclass:`SessionHandler` and :phpclass:`SessionHandlerInterface` are available. +Symfony 2.1 provides forward compatibility for the :phpclass:`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. +:phpclass:`SessionHandler` is a special PHP internal class which exposes native save +handlers to PHP user-space. 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` +class called :class:`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. @@ -595,11 +601,12 @@ 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` +:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage` +injects storage handlers into a handler proxy. The reason for this is that +under PHP 5.4, all handlers implement :phpclass:`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 +:phpclass:`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 From dadffe9059f0cbae943877dd06eb309498e67f39 Mon Sep 17 00:00:00 2001 From: Drak Date: Thu, 15 Mar 2012 09:27:05 +0545 Subject: [PATCH 3/3] Updated docs. --- components/http_foundation.rst | 202 ++++++++++++++++++++++++++++++--- 1 file changed, 185 insertions(+), 17 deletions(-) diff --git a/components/http_foundation.rst b/components/http_foundation.rst index b4433a5b763..2a51a743c80 100644 --- a/components/http_foundation.rst +++ b/components/http_foundation.rst @@ -401,6 +401,80 @@ Quick example:: echo $session->getFlashBag()->get('notice'); +Session API +~~~~~~~~~~~ + +The :class:`Symfony\\Component\\HttpFoundation\\Session\\Session` 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 + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::start`: + Starts the session - do not use `session_start()`. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::migrate`: + Starts the session - do not use `session_start()`. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::invalidate`: + Starts the session - do not use `session_start()`. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::getId`: Gets the + session ID. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::setId`: Gets the + session ID. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::getName`: Gets the + session name. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::setName`: Sets the + session name. + +Session attributes + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::set`: + Sets an attribute by key; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::get`: + Gets an attribute by key; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::all`: + Gets all attributes as an array of key => value; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::has`: + Returns true if the attribute exists; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::keys`: + Returns an array of stored attribute keys; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::replace`: + Sets multiple attributes at once: takes a keyed array and sets each key => value pair. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::remove`: + Deletes an attribute by key; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::clear`: + Clear the bag; + +Bag management + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::registerBag`: + Registers a `Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface` + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::getBag`: + Gets a `Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface` by + bag name. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::getFlashBag`: + Gets the `Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface`. + This is just a shortcut for convenience. + + + + Save Handlers ~~~~~~~~~~~~~ @@ -480,6 +554,20 @@ 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. +:class:`Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface` has +the following API which is intended mainly for internal purposes: + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface::getStorageKey`: + Returns the key which the bag will ultimately store its array under in `$_SESSION`. + Generally this value can be left at its default and is for internal use. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface::initialize`: + This is called internally by Symfony2 session storage classes to link bag data + to the session. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface::getName`: + Returns the name of the session bag. + Attributes ~~~~~~~~~~ @@ -518,6 +606,33 @@ structure like this using a namespace character (defaults to `/`):: 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 + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::set`: + Sets an attribute by key; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::get`: + Gets an attribute by key; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::all`: + Gets all attributes as an array of key => value; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::has`: + Returns true if the attribute exists; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::keys`: + Returns an array of stored attribute keys; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::replace`: + Sets multiple attributes at once: takes a keyed array and sets each key => value pair. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::remove`: + Deletes an attribute by key; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::clear`: + Clear the bag; + Flash messages ~~~~~~~~~~~~~~ @@ -539,6 +654,36 @@ This is however just one application for flash messages. they are explicitly retrieved or cleared. This makes it possible to use ESI caching. +:class:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface` +has a simple API + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::set`: + Sets a flash by type; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::get`: + Gets a flash by type and clears the flash from the bag; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::setAll`: + Sets an array of flashes by type => message; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::all`: + Gets all flashes and clears the flashes from the bag; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::peek`: + Gets a flash by type (read only); + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::peekAll`: + Gets all flashes (readoly); + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::has`: + Returns true if the type exists; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::keys`: + Returns an array of stored types; + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::clear`: + Clear the bag; + Testability ----------- @@ -554,8 +699,21 @@ 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. +The mock storage drivers do not read or write the system globals +`session_id()` or `session_name()`. Methods are provided to simulate this if +required: + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\SessionStorageInterface::getId`: Gets the + session ID. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\SessionStorageInterface::setId`: Gets the + session ID. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\SessionStorageInterface::getName`: Gets the + session name. + +* :method:`Symfony\\Component\\HttpFoundation\\Session\\SessionStorageInterface::setName`: Sets the + session name. Unit Testing ~~~~~~~~~~~~ @@ -584,9 +742,9 @@ separate PHP processes, simply change the storage engine to PHP 5.4 compatibility ~~~~~~~~~~~~~~~~~~~~~ -Since PHP 5.4.0, :phpclass:`SessionHandler` and :phpclass:`SessionHandlerInterface` are available. -Symfony 2.1 provides forward compatibility for the :phpclass:`SessionHandlerInterface` so -it can be used under PHP 5.3. This greatly improves inter-operability with other +Since PHP 5.4.0, :phpclass:`SessionHandler` and :phpclass:`SessionHandlerInterface` +are available. Symfony 2.1 provides forward compatibility for the :phpclass:`SessionHandlerInterface` +so it can be used under PHP 5.3. This greatly improves inter-operability with other libraries. :phpclass:`SessionHandler` is a special PHP internal class which exposes native save @@ -598,17 +756,27 @@ 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 -~~~~~~~~~~~~~ +Save Handler Proxy +~~~~~~~~~~~~~~~~~~ + +There are two kinds of save handler classes proxy which inherit from +:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\AbstractProxy`, +they are :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeProxy` +and :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\SessionHandlerProxy`. :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\NativeSessionStorage` -injects storage handlers into a handler proxy. The reason for this is that -under PHP 5.4, all handlers implement :phpclass:`SessionHandlerInterface` -including native handlers (those which activate internal PHP/PHP-extension -handlers. Native handlers under PHP 5.4 will be children of -:phpclass:`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. \ No newline at end of file +automatically injects storage handlers into a save handler proxy unless already +wrapped by one. + +:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\NativeProxy` +is used automatically under PHP 5.3 when internal PHP save handlers are specified +using the `Native*SessionHandler` classes, while +:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\SessionHandlerProxy` +will be used to wrap any custom save handlers, that implement :phpclass:`SessionHandlerInterface`. + +Under PHP 5.4 and above, all session handlers implement :phpclass:`SessionHandlerInterface` +including `Native*SessionHandler` classes which inherit from :phpclass:`SessionHandler`. + +The proxy mechanism allow you to get more deeply involved in session save handler +classes. A proxy for example could be used to encrypt any session transaction +without knowledge of the specific save handler.