99/**
1010 * Native PHP session implementation for SessionInterface.
1111 */
12+ /**
13+ * Native PHP session implementation for SessionInterface.
14+ * Supports optional configuration via configure() before start().
15+ */
1216final class Session implements SessionInterface
1317{
18+ /** @var array<string,mixed> */
19+ private array $ config = [];
20+
21+ /**
22+ * Configure session behavior (call before start()).
23+ * Supported keys: name, expire, path, cookie (array params for session_set_cookie_params), env
24+ * - path: when provided, ensures directory exists and sets session.save_path
25+ * - expire: accepts integer seconds
26+ */
27+ public function configure (array $ config = []): void
28+ {
29+ $ this ->config = $ config + $ this ->config ;
30+ }
31+
1432 /** @inheritDoc */
1533 public function start (): void
1634 {
17- if (session_status () !== PHP_SESSION_ACTIVE ) {
18- @session_start ();
35+ if (session_status () === PHP_SESSION_ACTIVE ) {
36+ return ;
37+ }
38+
39+ $ cfg = $ this ->applyDefaults ($ this ->config );
40+
41+ // Name
42+ if (!empty ($ cfg ['name ' ]) && is_string ($ cfg ['name ' ])) {
43+ @session_name ($ cfg ['name ' ]);
1944 }
45+
46+ // Cookie params
47+ if (!empty ($ cfg ['expire ' ])) {
48+ $ lifetime = (int ) $ cfg ['expire ' ];
49+ $ cookie = $ cfg ['cookie ' ] ?? [
50+ 'lifetime ' => $ lifetime ,
51+ 'path ' => '/ ' ,
52+ 'domain ' => '' ,
53+ 'secure ' => false ,
54+ 'httponly ' => true ,
55+ 'samesite ' => 'Lax ' ,
56+ ];
57+ @session_set_cookie_params ($ cookie );
58+ @ini_set ('session.gc_maxlifetime ' , (string ) $ lifetime );
59+ @ini_set ('session.gc_probability ' , '1 ' );
60+ @ini_set ('session.gc_divisor ' , '100 ' );
61+ }
62+
63+ // Path (create if missing)
64+ if (!empty ($ cfg ['path ' ])) {
65+ $ path = (string ) $ cfg ['path ' ];
66+ if (!is_dir ($ path )) {
67+ @mkdir ($ path , 0777 , true );
68+ }
69+ if (is_dir ($ path )) {
70+ @ini_set ('session.save_path ' , $ path );
71+ }
72+ }
73+
74+ @session_start ();
2075 }
2176
2277 /** @inheritDoc */
@@ -65,11 +120,34 @@ public function all(): array
65120 }
66121
67122 /** @inheritDoc */
68- public function destroy (): void
123+ public function destroy (? string $ key = null ): void
69124 {
125+ if ($ key !== null ) {
126+ unset($ _SESSION [$ key ]);
127+ return ;
128+ }
129+
70130 if (session_status () === PHP_SESSION_ACTIVE ) {
71131 @session_unset ();
72132 @session_destroy ();
73133 }
74134 }
135+
136+ /**
137+ * Apply default values similar to legacy Configuration::setSession
138+ * - expire: default 10 days (in seconds)
139+ * - path: defaults to storage_path('session') if available
140+ */
141+ private function applyDefaults (array $ config ): array
142+ {
143+ $ defaults = [
144+ 'name ' => null ,
145+ 'expire ' => 10 * 24 * 60 * 60 ,
146+ 'path ' => function_exists ('storage_path ' ) ? storage_path ('session ' ) : null ,
147+ 'cookie ' => null ,
148+ 'env ' => function_exists ('env ' ) ? env ('APP_ENV ' , 'production ' ) : 'production ' ,
149+ ];
150+
151+ return $ config + $ defaults ;
152+ }
75153}
0 commit comments