State Management in FW
FW runs as a persistent memory resident server using Swoole Coroutines. Because of this, traditional PHP Superglobals ($_SESSION) cannot be safely used. Standard session_start() would permanently poison the memory for all subsequent users.
To solve this, FW includes a completely asynchronous, PSR-16 compliant Distributed State Management package powered by Redis.
Cache API
The framework registers Psr\SimpleCache\CacheInterface with the Dependency Injection Container by default, bound to Fw\Framework\Cache\RedisCache.
You can inject the cache adapter directly into any handler or repository:
use Psr\SimpleCache\CacheInterface;
class LeaderboardHandler
{
public function __construct(private CacheInterface $cache) {}
public function __invoke(Request $request): JsonResponse
{
$stats = $this->cache->get('leaderboard_stats');
if (!$stats) {
$stats = $this->db->query("...");
$this->cache->set('leaderboard_stats', $stats, 3600); // Expiry in 1 hr
}
return new JsonResponse($stats);
}
}Session Management
Every HTTP Request boots a completely isolated SessionManager inside the pipeline coroutine. This prevents any data bleeding.
This Session is automatically mapped to an encrypted fw_session cookie on the client side, and data is actively retrieved from/saved to Redis transparently.
To read and write data to the user's active session, retrieve the SessionManager from the Symfony Request attributes inside your Controller/Handler:
use Symfony\Component\HttpFoundation\Request;
class CheckoutHandler
{
public function __invoke(Request $request): JsonResponse
{
/** @var \Fw\Framework\Http\Session\SessionManager $session */
$session = $request->attributes->get('session');
// Read from the user's secure Redis session payload
$cartIds = $session->get('cart_items', []);
// Write back to the payload
$cartIds[] = 142;
$session->set('cart_items', $cartIds);
// Optionally flush the ID to prevent fixation attacks
$session->regenerate();
return new JsonResponse(['success' => true]);
}
}Configuration
Swoole-safe State Management requires Redis. Ensure your .env is configured correctly:
REDIS_HOST=localhost
REDIS_PORT=6379