# Aura Session
Provides session management functionality, including lazy session starting,
session segments, next-request-only ("flash") values, and CSRF tools.
## Foreword
### Installation
This library requires PHP 5.3 or later; we recommend using the latest available version of PHP as a matter of principle. It has no userland dependencies.
It is installable and autoloadable via Composer as [aura/session](https://packagist.org/packages/aura/session).
Alternatively, [download a release](https://github.com/auraphp/Aura.Session/releases) or clone this repository, then require or include its _autoload.php_ file.
### Quality
[](https://scrutinizer-ci.com/g/auraphp/Aura.Session/)
[](https://scrutinizer-ci.com/g/auraphp/Aura.Session/)
[](https://travis-ci.org/auraphp/Aura.Session)
To run the unit tests at the command line, issue `composer install` and then `phpunit` at the package root. This requires [Composer](http://getcomposer.org/) to be available as `composer`, and [PHPUnit](http://phpunit.de/manual/) to be available as `phpunit`.
This library attempts to comply with [PSR-1][], [PSR-2][], and [PSR-4][]. If
you notice compliance oversights, please send a patch via pull request.
[PSR-1]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md
[PSR-2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
[PSR-4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md
### Community
To ask questions, provide feedback, or otherwise communicate with the Aura community, please join our [Google Group](http://groups.google.com/group/auraphp), follow [@auraphp on Twitter](http://twitter.com/auraphp), or chat with us on #auraphp on Freenode.
## Getting Started
### Instantiation
The easiest way to get started is to use the _SessionFactory_ to create a _Session_ manager object.
```php
newInstance($_COOKIE);
?>
```
We can then use the _Session_ instance to create _Segment_ objects to manage session values and flashes. (In general, we should not need to manipulate the _Session_ manager directly -- we will work mostly with _Segment_ objects.)
### Segments
In normal PHP, we keep session values in the `$_SESSION` array. However, when different libraries and projects try to modify the same keys, the resulting conflicts can result in unexpected behavior. To resolve this, we use _Segment_ objects. Each _Segment_ addresses a named key within the `$_SESSION` array for deconfliction purposes.
For example, if we get a _Segment_ for `Vendor\Package\ClassName`, that _Segment_ will contain a reference to `$_SESSION['Vendor\Package\ClassName']`. We can then `set()` and `get()` values on the _Segment_, and the values will reside in an array under that reference.
```php
getSegment('Vendor\Package\ClassName');
// try to get a value from the segment;
// if it does not exist, return an alternative value
echo $segment->get('foo'); // null
echo $segment->get('baz', 'not set'); // 'not set'
// set some values on the segment
$segment->set('foo', 'bar');
$segment->set('baz', 'dib');
// the $_SESSION array is now:
// $_SESSION = array(
// 'Vendor\Package\ClassName' => array(
// 'foo' => 'bar',
// 'baz' => 'dib',
// ),
// );
// try again to get a value from the segment
echo $segment->get('foo'); // 'bar'
// because the segment is a reference to $_SESSION, we can modify
// the superglobal directly and the segment values will also change
$_SESSION['Vendor\Package\ClassName']['zim'] = 'gir'
echo $segment->get('zim'); // 'gir'
?>
```
The benefit of a session segment is that we can deconflict the keys in the
`$_SESSION` superglobal by using class names (or some other unique name) for
the segment names. With segments, different packages can use the `$_SESSION`
superglobal without stepping on each other's toes.
To clear all the values on a _Segment_, use the `clear()` method.
### Flash Values
_Segment_ values persist until the session is cleared or destroyed. However, sometimes it is useful to set a value that propagates only through the next request, and is then discarded. These are called "flash" values.
#### Setting And Getting Flash Values
To set a flash value on a _Segment_, use the `setFlash()` method.
```php
getSegment('Vendor\Package\ClassName');
$segment->setFlash('message', 'Hello world!');
?>
```
Then, in subsequent requests, we can read the flash value using `getFlash()`:
```php
getSegment('Vendor\Package\ClassName');
$message = $segment->getFlash('message'); // 'Hello world!'
?>
```
> N.b. As with `get()`, we can provide an alternative value if the flash key does not exist. For example, `getFlash('foo', 'not set')` will return 'not set' if there is no 'foo' key available.
Using `setFlash()` makes the flash value available only in the *next* request, not the current one. To make the flash value available immediately as well as in the next request, use `setFlashNow($key, $val)`.
Using `getFlash()` returns only the values that are available now from having been set in the previous request. To read a value that will be available in the next request, use `getFlashNext($key, $alt)`.
#### Keeping and Clearing Flash Values
Sometimes we will want to keep the flash values in the current request for the next request. We can do so on a per-segment basis by calling the _Segment_ `keepFlash()` method, or we can keep all flashes for all segments by calling the _Session_ `keepFlash()` method.
Similarly, we can clear flash values on a per-segment basis or a session-wide bases. Use the `clearFlash()` method on the _Segment_ to clear flashes just for that segment, or the same method on the _Session_ to clear all flash values for all segments.
### Lazy Session Starting
Merely instantiating the _Session_ manager and getting a _Segment_ from it does *not* call `session_start()`. Instead, `session_start()` occurs only in certain circumstances:
- If we *read* from a _Segment_ (e.g. with `get()`) the _Session_ looks to see if a session cookie has already been set. If so, it will call `session_start()` to resume the previously-started session. If not, it knows there are no previously existing `$_SESSION` values, so it will not call `session_start()`.
- If we *write* to a _Segment_ (e.g. with `set()`) the _Session_ will always call `session_start()`. This will resume a previous session if it exists, or start a new one if it does not.
This means we can create each _Segment_ at will, and `session_start()` will not be invoked until we actually interact with a _Segment_ in a particular way. This helps to conserve the resources involved in starting a session.
Of course, we can force a session start or reactivation by calling the _Session_ `start()` method, but that defeats the purpose of lazy-loaded sessions.
### Saving, Clearing, and Destroying Sessions
> N.b.: These methods apply to all session data and flashes across all segments.
To save the session data and end its use during the current request, call the `commit()` method on the _Session_ manager:
```php
commit();
?>
```
> N.b.: Per