Skip to content

Commit ae035d4

Browse files
committed
feat: add Sessions guide with configuration and usage details
1 parent 183af06 commit ae035d4

2 files changed

Lines changed: 199 additions & 0 deletions

File tree

src/.vitepress/config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export default defineConfig({
4848
{ text: 'Caching', link: '/guide/caching' },
4949
{ text: 'Crypto', link: '/guide/crypto' },
5050
{ text: 'Scheduling', link: '/guide/scheduling' },
51+
{ text: 'Sessions', link: '/guide/sessions' },
5152
{ text: 'Tasks', link: '/guide/tasks' },
5253
{ text: 'Queues', link: '/guide/queues' },
5354
{ text: 'Events', link: '/guide/events' },

src/guide/sessions.md

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# Sessions
2+
3+
## Table of Contents
4+
5+
- [Introduction](#introduction)
6+
- [Configuration](#configuration)
7+
- [Session Driver](#session-driver)
8+
- [Cookie Options](#cookie-options)
9+
- [Environment Variables](#environment-variables)
10+
- [Using Session in Controllers](#using-session-in-controllers)
11+
- [Session API in `Phenix\Http\Session`](#session-api-in-phenixhttpsession)
12+
- [Quick methods](#quick-methods)
13+
- [Advanced lock/transaction methods](#advanced-locktransaction-methods)
14+
- [Using Session in Middlewares](#using-session-in-middlewares)
15+
- [How Session Integration Works in Phenix](#how-session-integration-works-in-phenix)
16+
- [Notes and Current Behaviors](#notes-and-current-behaviors)
17+
18+
## Introduction
19+
20+
Phenix session support is built on top of [`amphp/http-server-session`](https://amphp.org/http-server-session).
21+
22+
Supported session drivers are:
23+
24+
- `local`
25+
- `redis`
26+
27+
Sessions in this guide are HTTP sessions for per-client state. They are not an authentication system by themselves.
28+
29+
## Configuration
30+
31+
Session configuration lives in `config/session.php`.
32+
33+
```php
34+
return [
35+
'driver' => env('SESSION_DRIVER', static fn (): string => 'local'),
36+
'lifetime' => env('SESSION_LIFETIME', static fn (): int => 120),
37+
'connection' => env('SESSION_CONNECTION', static fn () => 'default'),
38+
'cookie_name' => env('SESSION_COOKIE_NAME', ...),
39+
'path' => '/',
40+
'domain' => env('SESSION_DOMAIN'),
41+
'secure' => env('SESSION_SECURE_COOKIE'),
42+
'http_only' => true,
43+
'same_site' => 'Lax',
44+
];
45+
```
46+
47+
### Session Driver
48+
49+
- `local`: in-memory storage (`LocalSessionStorage`)
50+
- `redis`: Redis-backed storage (`RedisSessionStorage`)
51+
52+
When `driver=redis`, Phenix uses `session.connection` and resolves it against `config/database.php` under `database.redis.connections`.
53+
54+
### Cookie Options
55+
56+
Cookie attributes are built from session config and host:
57+
58+
- `domain`: `session.domain` (or current app host if null)
59+
- `expiry`: current time + `session.lifetime` minutes
60+
- `same_site`: `Lax`, `Strict`, or `None`
61+
- `path`: `session.path`
62+
- `http_only`: enabled when `session.http_only=true`
63+
- `secure`: enabled when `session.secure=true`
64+
- cookie name: `session.cookie_name`
65+
66+
### Environment Variables
67+
68+
- `SESSION_DRIVER` (`local` or `redis`)
69+
- `SESSION_LIFETIME` (minutes)
70+
- `SESSION_CONNECTION` (Redis connection name)
71+
- `SESSION_COOKIE_NAME`
72+
- `SESSION_DOMAIN`
73+
- `SESSION_SECURE_COOKIE`
74+
75+
For Redis connection details, configure `REDIS_*` variables in `config/database.php`.
76+
77+
## Using Session in Controllers
78+
79+
Controller actions receive `Phenix\Http\Request`, which exposes:
80+
81+
- `$request->session()` to get the `Phenix\Http\Session` object
82+
- `$request->session('key', $default)` to read a value directly
83+
84+
Example:
85+
86+
```php
87+
<?php
88+
89+
declare(strict_types=1);
90+
91+
namespace App\Http\Controllers;
92+
93+
use Phenix\Http\Controller;
94+
use Phenix\Http\Request;
95+
use Phenix\Http\Response;
96+
97+
class ProfileController extends Controller
98+
{
99+
public function updateLocale(Request $request): Response
100+
{
101+
$session = $request->session();
102+
103+
$session->put('locale', 'es');
104+
105+
return response()->json([
106+
'locale' => $request->session('locale', 'en'),
107+
]);
108+
}
109+
}
110+
```
111+
112+
## Session API in `Phenix\Http\Session`
113+
114+
`Phenix\Http\Session` wraps Amp's session object and exposes convenient methods.
115+
116+
### Quick methods
117+
118+
- `get(string $name, mixed $default = null): mixed`
119+
- `set(string $name, mixed $value): void`
120+
- `put(string $name, mixed $value): void` (locks + sets + commits)
121+
- `has(string $name): bool`
122+
- `delete(string $name): void`
123+
- `clear(): void`
124+
- `refresh(): void` (regenerates session ID)
125+
- `getId(): ?string`
126+
- `getData(): array`
127+
- `isRead(): bool`
128+
- `isLocked(): bool`
129+
- `isEmpty(): bool`
130+
131+
### Advanced lock/transaction methods
132+
133+
- `lock(): void`
134+
- `commit(): void`
135+
- `rollback(): void`
136+
- `unlock(): void`
137+
- `unlockAll(): void`
138+
139+
Use these when you need explicit control over write/rollback flow.
140+
141+
## Using Session in Middlewares
142+
143+
When you are inside an Amp middleware (`Amp\Http\Server\Middleware`), use the session exactly as documented by `amphp/http-server-session`: read it from request attributes.
144+
145+
```php
146+
<?php
147+
148+
declare(strict_types=1);
149+
150+
namespace App\Http\Middleware;
151+
152+
use Amp\Http\Server\Middleware;
153+
use Amp\Http\Server\Request;
154+
use Amp\Http\Server\RequestHandler;
155+
use Amp\Http\Server\Response;
156+
use Amp\Http\Server\Session\Session;
157+
158+
class TrackVisits implements Middleware
159+
{
160+
public function handleRequest(Request $request, RequestHandler $next): Response
161+
{
162+
/** @var Session $session */
163+
$session = $request->getAttribute(Session::class);
164+
165+
$session->lock();
166+
$session->set('visits', ((int) $session->get('visits')) + 1);
167+
$session->commit();
168+
169+
return $next->handleRequest($request);
170+
}
171+
}
172+
```
173+
174+
In other words:
175+
176+
- In controllers, use `Phenix\Http\Request::session()`.
177+
- In Amp middlewares, use `Amp\Http\Server\Request::getAttribute(Session::class)`.
178+
179+
## How Session Integration Works in Phenix
180+
181+
At runtime, Phenix wires sessions in this flow:
182+
183+
1. `Phenix\App` appends a session middleware globally (`SessionMiddlewareFactory::make(...)`).
184+
2. `Phenix\Session\SessionMiddlewareFactory` creates an Amp `SessionMiddleware` using:
185+
- `LocalSessionStorage` for `session.driver=local`
186+
- `RedisSessionStorage` for `session.driver=redis`
187+
3. The middleware injects `Amp\Http\Server\Session\Session` into request attributes.
188+
4. `Phenix\Http\Request` detects that attribute and wraps it into `Phenix\Http\Session`.
189+
5. In controllers, you access it via `$request->session()`.
190+
191+
Because this middleware is appended by the framework, you do not need to manually register it in `config/app.php`.
192+
193+
## Notes and Current Behaviors
194+
195+
- Session middleware is automatically appended to the global middleware stack by the framework.
196+
- `request->session()` depends on that middleware; in normal app flow it is available.
197+
- Session cookie is sent/read by Amp session middleware.
198+
- Session state management is independent from Phenix authentication modules.

0 commit comments

Comments
 (0)