发布于 2015-08-27 16:42:21 | 221 次阅读 | 评论: 0 | 来源: 网络整理
The Symfony 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 Session
implementation of SessionInterface
interface.
警告
Make sure your PHP session isn’t already started before using the Session class. If you have a legacy session system that starts your session, see Legacy Sessions.
Quick example:
use SymfonyComponentHttpFoundationSessionSession;
$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>';
}
注解
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.
注解
While it is recommended to explicitly start a session, a session will actually start on demand, that is, if any session request is made to read/write session data.
警告
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
.
The Session
class implements
SessionInterface
.
The Session
has a simple API
as follows divided into a couple of groups.
start()
session_start()
.migrate()
session_regenerate_id()
.
This method can optionally change the lifetime of the new cookie that will
be emitted by calling this method.invalidate()
session_destroy()
.getId()
session_id()
.setId()
session_id()
.getName()
session_name()
.setName()
session_name()
.set()
get()
all()
has()
replace()
remove()
clear()
The attributes are stored internally in a “Bag”, a PHP object that acts like an array. A few methods exist for “Bag” management:
registerBag()
SessionBagInterface
.getBag()
SessionBagInterface
by
bag name.getFlashBag()
FlashBagInterface
.
This is just a shortcut for convenience.getMetadataBag()
MetadataBag
which contains information about the session.PHP’s session management requires the use of the $_SESSION
super-global,
however, this interferes somewhat with code testability and encapsulation in an
OOP paradigm. To help overcome this, Symfony 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 Symfony to peacefully co-exist with other applications or libraries
that might use the $_SESSION
super-global and all data remains completely
compatible with Symfony’s session management.
Symfony provides two 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.
SessionBagInterface
has
the following API which is intended mainly for internal purposes:
getStorageKey()
$_SESSION
.
Generally this value can be left at its default and is for internal use.initialize()
getName()
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
NamespacedAttributeBag
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.
AttributeBagInterface
has a simple API
set()
get()
all()
has()
keys()
replace()
remove()
clear()
The purpose of the FlashBagInterface
is to provide a way of setting and retrieving messages on a per session basis.
The usual workflow would be to set flash messages in a request and to display them
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.
AutoExpireFlashBag
FlashBag
FlashBagInterface
has a simple API
add()
set()
string
or multiple messages in an array
.get()
setAll()
type => array(messages)
.all()
peek()
peekAll()
has()
keys()
clear()
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 SymfonyComponentHttpFoundationSessionSession;
$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 as follows.
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>';
}
}