承接 codemonster-ru/session 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

codemonster-ru/session

最新稳定版本:v2.0.0

Composer 安装命令:

composer require codemonster-ru/session

包简介

Lightweight session management library for PHP with pluggable handlers

README 文档

README

Latest Version on Packagist Total Downloads License Tests Coverage

Lightweight session management library for PHP - object-oriented.

Installation

composer require codemonster-ru/session

Usage

Basic example

use Codemonster\Session\Session; // Start session (default: file storage) Session::start(); // Store values Session::put('user', 'Vasya'); Session::put('role', 'admin'); // Retrieve values echo Session::get('user'); // Vasya // Remove values Session::forget('role'); // Get all session data print_r(Session::all()); // Destroy current session Session::destroy();

Regenerating session ID (fixation protection)

// Rotate ID after login or privilege change Session::regenerate();

Regenerating on start

// Force new ID at start (keeps data, destroys old session) Session::start(options: ['regenerate' => true]);

Cookie options

Session::start(options: [ 'cookie' => [ 'secure' => true, 'samesite' => 'Strict', 'lifetime' => 3600, 'path' => '/', 'domain' => 'example.com' ] ]);

Notes:

  • If secure is not provided, it is set automatically when HTTPS is detected.
  • If samesite is None, secure is forced to true.

Production cookie example

Session::start(options: [ 'cookie' => [ 'secure' => true, 'httponly' => true, 'samesite' => 'Strict', 'lifetime' => 60 * 60 * 24, 'path' => '/' ] ]);

Encryption

use Codemonster\Session\Session; $key = random_bytes(32); Session::start(options: [ 'encryption' => [ 'key' => $key, // Optional: allow decrypting existing plaintext sessions // Also triggers auto-migration to encrypted payload on first read 'allow_plaintext' => true, // Optional: previous keys for rotation 'previous_keys' => [] ] ]);

Encryption key rotation

$oldKey = random_bytes(32); $newKey = random_bytes(32); Session::start(options: [ 'encryption' => [ 'key' => $oldKey, 'allow_plaintext' => true ] ]); // rotate to a new key, keeping the old key for decryption Session::rotateEncryptionKey($newKey, [$oldKey]);

Production encryption example

// Store keys in env/secret manager; use base64 for readability. $currentKey = base64_decode(getenv('SESSION_KEY'), true); $previousKey = base64_decode(getenv('SESSION_KEY_PREV'), true); Session::start(options: [ 'encryption' => [ 'key' => $currentKey, 'previous_keys' => array_filter([$previousKey]), 'allow_plaintext' => false ] ]);

Key rotation strategy

  1. Deploy with previous_keys containing the old key and key as the new key.
  2. Keep allow_plaintext=false if you already migrated to encryption.
  3. After rotation window, remove the old key from previous_keys.

Using Array handler (for tests or CLI)

Session::start('array'); Session::put('debug', true); echo Session::get('debug'); // true

Handy helpers

Session::put('count', 1); Session::increment('count', 2); // 3 Session::put('token', 'abc'); Session::has('token'); // true Session::pull('token'); // 'abc' Session::has('token'); // false Session::put('a', 1); Session::put('b', 2); Session::forgetMany(['a', 'b']); // Flash data lasts for the next start and is then removed Session::flash('notice', 'Saved');

TTL for keys

Session::putWithTtl('token', 'abc', 60); // expires in 60 seconds Session::sweepExpired(); // optional manual cleanup Session::ttl('token'); // remaining seconds Session::expiresAt('token'); // unix timestamp Session::touch('token', 120); // extend TTL

Namespaced sessions

$admin = Session::for('admin'); $user = Session::for('user'); $admin->put('token', 'admin123'); $user->put('token', 'user456');

Namespace helpers

$admin = Session::for('admin'); $admin->keys(); // ['token', ...] $admin->forgetNamespace(); Session::count(); // count of user keys Session::touchAll(120); // extend TTL for all keys Session::touchAll(120, 'admin.'); // extend only for namespace Session::keys(); // ['admin.token', 'user.token', ...] Session::forgetNamespace('user');

Custom namespace delimiter

$scope = Session::for('admin', ':'); $scope->put('token', 'x'); // stored as admin:token

Debug helpers

Session::dump(); // array of user-visible keys/values Session::dump(['token']); // redact selected keys Session::dump([], ['user*']); // redact by pattern Session::size(); // payload size in bytes

Key helpers

Session::keys(); // all keys Session::keysMatch('user*'); // wildcard match

Session manager (non-static)

$manager = Session::manager(); $manager->put('token', 'abc'); $scoped = $manager->for('admin'); $scoped->put('token', 'admin123');

Using custom handler

use Codemonster\Session\Session; use App\Session\RedisSessionHandler; $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $handler = new RedisSessionHandler($redis); Session::start(customHandler: $handler); Session::put('user_id', 42);

Using Redis handler

use Codemonster\Session\Handlers\RedisSessionHandler; use Codemonster\Session\Session; $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $handler = new RedisSessionHandler($redis, prefix: 'sess_', ttl: 3600, retries: 2, retryDelayMs: 100); Session::start(customHandler: $handler);

Using Redis Cluster handler

use Codemonster\Session\Handlers\RedisClusterSessionHandler; use Codemonster\Session\Session; $cluster = new RedisCluster(null, ['127.0.0.1:7000', '127.0.0.1:7001']); $handler = new RedisClusterSessionHandler($cluster, prefix: 'sess_', ttl: 3600, retries: 2, retryDelayMs: 100); Session::start(customHandler: $handler);

Using Redis Sentinel handler

use Codemonster\Session\Handlers\RedisSentinelSessionHandler; use Codemonster\Session\Session; $sentinel = new RedisSentinel('127.0.0.1', 26379); $handler = new RedisSentinelSessionHandler( $sentinel, service: 'mymaster', prefix: 'sess_', ttl: 3600, retries: 2, retryDelayMs: 100 ); Session::start(customHandler: $handler);

Using Predis handler

use Codemonster\Session\Handlers\PredisSessionHandler; use Codemonster\Session\Session; use Predis\Client; $client = new Client('tcp://127.0.0.1:6379'); $handler = new PredisSessionHandler($client, prefix: 'sess_', ttl: 3600, retries: 2, retryDelayMs: 100); Session::start(customHandler: $handler);

Using PSR-16 cache handler

use Codemonster\Session\Handlers\CacheSessionHandler; use Codemonster\Session\Session; use Psr\SimpleCache\CacheInterface; /** @var CacheInterface $cache */ $handler = new CacheSessionHandler($cache, prefix: 'sess_', ttl: 3600, retries: 2, retryDelayMs: 100); Session::start(customHandler: $handler);

Testing

You can run tests with the command:

composer test

Static analysis:

composer analyse composer psalm

Redis integration tests (optional):

REDIS_TESTS=1 composer test

Redis Sentinel/Cluster integration tests (optional):

REDIS_SENTINEL_TESTS=1 composer test REDIS_CLUSTER_TESTS=1 composer test

Stress test (optional):

composer stress composer stress -- 20000 array composer stress -- 20000 file REDIS_HOST=127.0.0.1 REDIS_PORT=6379 composer stress -- 20000 redis # With thresholds: iterations, driver, min_ops, max_seconds composer stress -- 20000 array 3400 6 composer stress -- 10000 file 1700 6 composer stress -- 20000 redis 400 6

Note: thresholds depend on runner performance; recalibrate if CI hardware changes.

Security

Security reports: email admin@codemonster.net with a clear description and steps to reproduce.

Security checklist:

  • Use HTTPS and secure cookies in production.
  • Set SameSite to Strict or Lax based on your flow.
  • Use httponly to reduce XSS access to cookies.
  • Rotate session IDs after login or privilege changes.
  • Consider payload encryption (encryption.key) for sensitive data.
  • Keep session storage private and with proper file permissions.

Author

Kirill Kolesnikov

License

MIT

统计信息

  • 总下载量: 137
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 3
  • 依赖项目数: 2
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-01-04

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固