Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
82 / 82
100.00% covered (success)
100.00%
57 / 57
47.22% covered (danger)
47.22%
34 / 72
100.00% covered (success)
100.00%
16 / 16
CRAP
100.00% covered (success)
100.00%
1 / 1
Session
100.00% covered (success)
100.00%
82 / 82
100.00% covered (success)
100.00%
57 / 57
47.22% covered (danger)
47.22%
34 / 72
100.00% covered (success)
100.00%
16 / 16
250.29
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 start
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
17 / 17
19.51% covered (danger)
19.51%
8 / 41
100.00% covered (success)
100.00%
1 / 1
62.14
 destroy
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
8 / 8
37.50% covered (danger)
37.50%
3 / 8
100.00% covered (success)
100.00%
1 / 1
11.10
 name
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 id
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 all
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 clear
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 pull
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 set
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 has
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 remove
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 active
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 close
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 regenerate
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 assertActive
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Celema\Session;
6
7use SessionHandlerInterface;
8use SessionUpdateTimestampHandlerInterface;
9
10/** @api */
11class Session
12{
13    private const array DEFAULT_OPTIONS = [
14        'cache_limiter' => 'nocache',
15        'cookie_httponly' => true,
16        'cookie_samesite' => 'Lax',
17        'cookie_secure' => true,
18        'use_only_cookies' => true,
19        'use_strict_mode' => true,
20        'use_trans_sid' => false,
21    ];
22
23    protected readonly array $options;
24
25    /** @psalm-suppress UnusedProperty Used by the $flash property hook. */
26    private ?Flash $flashInstance = null;
27
28    /** @psalm-suppress UnusedProperty Used by the $csrf property hook. */
29    private ?Csrf $csrfInstance = null;
30
31    /** @psalm-suppress UnusedProperty Used by the $uri property hook. */
32    private ?Uri $uriInstance = null;
33
34    /** @psalm-suppress UnusedProperty Used by helper property hooks. */
35    private readonly Contract\Helpers $helpers;
36
37    /** @psalm-suppress PropertyNotSetInConstructor Virtual property backed by a get hook. */
38    public Flash $flash {
39        get => $this->flashInstance ??= $this->helpers->flash($this);
40    }
41
42    /** @psalm-suppress PropertyNotSetInConstructor Virtual property backed by a get hook. */
43    public Csrf $csrf {
44        get => $this->csrfInstance ??= $this->helpers->csrf($this);
45    }
46
47    /** @psalm-suppress PropertyNotSetInConstructor Virtual property backed by a get hook. */
48    public Uri $uri {
49        get => $this->uriInstance ??= $this->helpers->uri($this);
50    }
51
52    public function __construct(
53        array $options = [],
54        protected readonly string $name = '',
55        protected readonly ?SessionHandlerInterface $handler = null,
56        Contract\Helpers $helpers = new Helpers(),
57    ) {
58        $this->options = array_replace(self::DEFAULT_OPTIONS, $options);
59        $this->helpers = $helpers;
60    }
61
62    public function start(): void
63    {
64        if (session_status() !== PHP_SESSION_NONE) {
65            return;
66        }
67
68        if (headers_sent($file, $line)) {
69            // Requires sent headers, which the test suite cannot trigger reliably.
70            // @codeCoverageIgnoreStart
71            throw new RuntimeException(
72                __METHOD__ . 'Session started after headers sent. File: ' . $file . ' line: ' . $line,
73            );
74
75            // @codeCoverageIgnoreEnd
76        }
77
78        if ($this->name) {
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
85            && $this->options['use_strict_mode']
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
87        ) {
88            throw new RuntimeException(
89                'Session handler must implement SessionUpdateTimestampHandlerInterface to support strict mode',
90            );
91        }
92
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
94            throw new RuntimeException('Session handler setup failed');
95        }
96
97        if (!session_start($this->options)) {
98            // session_start() only returns false after PHP accepts the setup but fails internally;
99            // forcing that path would make the test process depend on unstable runtime state.
100            throw new RuntimeException(__METHOD__ . 'session_start failed.'); // @codeCoverageIgnore
101        }
102    }
103
104    public function destroy(): void
105    {
106        $this->assertActive();
107
108        session_unset();
109
110        $useCookies = ini_get('session.use_cookies');
111        if ($useCookies === '1') {
112            $params = session_get_cookie_params();
113            $name = session_name();
114            if ($name !== false) {
115                /** @psalm-suppress InvalidArrayOffset PHP 8.5 exposes partitioned cookies. */
116                $options = [
117                    'expires' => time() - 42000,
118                    'path' => $params['path'],
119                    'secure' => $params['secure'],
120                    'httponly' => $params['httponly'],
121                    'samesite' => $params['samesite'],
122                    'partitioned' => $params['partitioned'],
123                ];
124
125                $domain = $params['domain'];
126                if ($domain !== '') {
127                    $options['domain'] = $domain;
128                }
129
130                setcookie($name, '', $options);
131            }
132        }
133
134        if (!session_destroy()) {
135            throw new RuntimeException('Session destroy failed');
136        }
137    }
138
139    public function name(): string
140    {
141        $name = session_name();
142        if ($name === false) {
143            throw new RuntimeException('Session name not available');
144        }
145
146        return $name;
147    }
148
149    public function id(): string
150    {
151        $id = session_id();
152        if ($id === false) {
153            throw new RuntimeException('Session id not available');
154        }
155
156        return $id;
157    }
158
159    /** @return array<array-key, mixed> */
160    public function all(): array
161    {
162        $this->assertActive();
163
164        /**
165         * @var array<array-key, mixed> $session
166         * @mago-expect lint:inline-variable-return Keep the explicit type for `$_SESSION`.
167         */
168        $session = $_SESSION;
169
170        return $session;
171    }
172
173    public function clear(): void
174    {
175        $this->assertActive();
176
177        session_unset();
178    }
179
180    /** @param non-empty-string $key */
181    public function get(string $key, mixed $default = null): mixed
182    {
183        if ($this->has($key)) {
184            return $_SESSION[$key];
185        }
186
187        if (func_num_args() > 1) {
188            return $default;
189        }
190
191        throw new OutOfBoundsException(
192            "The session key '{$key}' does not exist",
193        );
194    }
195
196    /**
197     * @psalm-suppress MixedAssignment
198     * @param non-empty-string $key
199     */
200    public function pull(string $key, mixed $default = null): mixed
201    {
202        if ($this->has($key)) {
203            $value = $_SESSION[$key];
204            unset($_SESSION[$key]);
205
206            return $value;
207        }
208
209        if (func_num_args() > 1) {
210            return $default;
211        }
212
213        throw new OutOfBoundsException(
214            "The session key '{$key}' does not exist",
215        );
216    }
217
218    /**
219     * @psalm-suppress MixedAssignment
220     * @param non-empty-string $key
221     * */
222    public function set(string $key, mixed $value): void
223    {
224        $this->assertActive();
225
226        $_SESSION[$key] = $value;
227    }
228
229    /** @param non-empty-string $key */
230    public function has(string $key): bool
231    {
232        $this->assertActive();
233
234        return ($_SESSION[$key] ?? null) !== null;
235    }
236
237    /** @param non-empty-string $key */
238    public function remove(string $key): void
239    {
240        $this->assertActive();
241
242        unset($_SESSION[$key]);
243    }
244
245    public function active(): bool
246    {
247        return session_status() === PHP_SESSION_ACTIVE;
248    }
249
250    public function close(): void
251    {
252        $this->assertActive();
253
254        if (!session_write_close()) {
255            throw new RuntimeException('Session close failed');
256        }
257    }
258
259    public function regenerate(): void
260    {
261        $this->assertActive();
262
263        if (!session_regenerate_id(true)) {
264            throw new RuntimeException('Session id regeneration failed');
265        }
266
267        // A token issued before a login must not stay valid for the session after it.
268        $this->csrf->clear();
269    }
270
271    private function assertActive(): void
272    {
273        if (!$this->active()) {
274            throw new RuntimeException('Session not started');
275        }
276    }
277}

Paths

Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once. Please also be aware that some paths may include implicit rather than explicit branches, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.

Session->$csrf::get
44        get => $this->csrfInstance ??= $this->helpers->csrf($this);
Session->$flash::get
39        get => $this->flashInstance ??= $this->helpers->flash($this);
Session->$uri::get
49        get => $this->uriInstance ??= $this->helpers->uri($this);
Session->__construct
53        array $options = [],
54        protected readonly string $name = '',
55        protected readonly ?SessionHandlerInterface $handler = null,
56        Contract\Helpers $helpers = new Helpers(),
57    ) {
58        $this->options = array_replace(self::DEFAULT_OPTIONS, $options);
59        $this->helpers = $helpers;
60    }
Session->active
247        return session_status() === PHP_SESSION_ACTIVE;
248    }
Session->all
162        $this->assertActive();
163
164        /**
165         * @var array<array-key, mixed> $session
166         * @mago-expect lint:inline-variable-return Keep the explicit type for `$_SESSION`.
167         */
168        $session = $_SESSION;
169
170        return $session;
171    }
Session->assertActive
273        if (!$this->active()) {
 
274            throw new RuntimeException('Session not started');
273        if (!$this->active()) {
 
276    }
Session->clear
175        $this->assertActive();
176
177        session_unset();
178    }
Session->close
252        $this->assertActive();
253
254        if (!session_write_close()) {
 
255            throw new RuntimeException('Session close failed');
252        $this->assertActive();
253
254        if (!session_write_close()) {
 
257    }
Session->destroy
106        $this->assertActive();
107
108        session_unset();
109
110        $useCookies = ini_get('session.use_cookies');
111        if ($useCookies === '1') {
 
112            $params = session_get_cookie_params();
113            $name = session_name();
114            if ($name !== false) {
 
117                    'expires' => time() - 42000,
118                    'path' => $params['path'],
119                    'secure' => $params['secure'],
120                    'httponly' => $params['httponly'],
121                    'samesite' => $params['samesite'],
122                    'partitioned' => $params['partitioned'],
123                ];
124
125                $domain = $params['domain'];
126                if ($domain !== '') {
 
127                    $options['domain'] = $domain;
128                }
129
130                setcookie($name, '', $options);
 
130                setcookie($name, '', $options);
131            }
132        }
133
134        if (!session_destroy()) {
 
134        if (!session_destroy()) {
 
135            throw new RuntimeException('Session destroy failed');
106        $this->assertActive();
107
108        session_unset();
109
110        $useCookies = ini_get('session.use_cookies');
111        if ($useCookies === '1') {
 
112            $params = session_get_cookie_params();
113            $name = session_name();
114            if ($name !== false) {
 
117                    'expires' => time() - 42000,
118                    'path' => $params['path'],
119                    'secure' => $params['secure'],
120                    'httponly' => $params['httponly'],
121                    'samesite' => $params['samesite'],
122                    'partitioned' => $params['partitioned'],
123                ];
124
125                $domain = $params['domain'];
126                if ($domain !== '') {
 
127                    $options['domain'] = $domain;
128                }
129
130                setcookie($name, '', $options);
 
130                setcookie($name, '', $options);
131            }
132        }
133
134        if (!session_destroy()) {
 
134        if (!session_destroy()) {
 
137    }
106        $this->assertActive();
107
108        session_unset();
109
110        $useCookies = ini_get('session.use_cookies');
111        if ($useCookies === '1') {
 
112            $params = session_get_cookie_params();
113            $name = session_name();
114            if ($name !== false) {
 
117                    'expires' => time() - 42000,
118                    'path' => $params['path'],
119                    'secure' => $params['secure'],
120                    'httponly' => $params['httponly'],
121                    'samesite' => $params['samesite'],
122                    'partitioned' => $params['partitioned'],
123                ];
124
125                $domain = $params['domain'];
126                if ($domain !== '') {
 
130                setcookie($name, '', $options);
131            }
132        }
133
134        if (!session_destroy()) {
 
134        if (!session_destroy()) {
 
135            throw new RuntimeException('Session destroy failed');
106        $this->assertActive();
107
108        session_unset();
109
110        $useCookies = ini_get('session.use_cookies');
111        if ($useCookies === '1') {
 
112            $params = session_get_cookie_params();
113            $name = session_name();
114            if ($name !== false) {
 
117                    'expires' => time() - 42000,
118                    'path' => $params['path'],
119                    'secure' => $params['secure'],
120                    'httponly' => $params['httponly'],
121                    'samesite' => $params['samesite'],
122                    'partitioned' => $params['partitioned'],
123                ];
124
125                $domain = $params['domain'];
126                if ($domain !== '') {
 
130                setcookie($name, '', $options);
131            }
132        }
133
134        if (!session_destroy()) {
 
134        if (!session_destroy()) {
 
137    }
106        $this->assertActive();
107
108        session_unset();
109
110        $useCookies = ini_get('session.use_cookies');
111        if ($useCookies === '1') {
 
112            $params = session_get_cookie_params();
113            $name = session_name();
114            if ($name !== false) {
 
134        if (!session_destroy()) {
 
135            throw new RuntimeException('Session destroy failed');
106        $this->assertActive();
107
108        session_unset();
109
110        $useCookies = ini_get('session.use_cookies');
111        if ($useCookies === '1') {
 
112            $params = session_get_cookie_params();
113            $name = session_name();
114            if ($name !== false) {
 
134        if (!session_destroy()) {
 
137    }
106        $this->assertActive();
107
108        session_unset();
109
110        $useCookies = ini_get('session.use_cookies');
111        if ($useCookies === '1') {
 
134        if (!session_destroy()) {
 
135            throw new RuntimeException('Session destroy failed');
106        $this->assertActive();
107
108        session_unset();
109
110        $useCookies = ini_get('session.use_cookies');
111        if ($useCookies === '1') {
 
134        if (!session_destroy()) {
 
137    }
Session->get
181    public function get(string $key, mixed $default = null): mixed
182    {
183        if ($this->has($key)) {
 
184            return $_SESSION[$key];
181    public function get(string $key, mixed $default = null): mixed
182    {
183        if ($this->has($key)) {
 
187        if (func_num_args() > 1) {
 
188            return $default;
181    public function get(string $key, mixed $default = null): mixed
182    {
183        if ($this->has($key)) {
 
187        if (func_num_args() > 1) {
 
191        throw new OutOfBoundsException(
192            "The session key '{$key}' does not exist",
193        );
194    }
Session->has
230    public function has(string $key): bool
231    {
232        $this->assertActive();
233
234        return ($_SESSION[$key] ?? null) !== null;
235    }
Session->id
151        $id = session_id();
152        if ($id === false) {
 
153            throw new RuntimeException('Session id not available');
151        $id = session_id();
152        if ($id === false) {
 
156        return $id;
157    }
Session->name
141        $name = session_name();
142        if ($name === false) {
 
143            throw new RuntimeException('Session name not available');
141        $name = session_name();
142        if ($name === false) {
 
146        return $name;
147    }
Session->pull
200    public function pull(string $key, mixed $default = null): mixed
201    {
202        if ($this->has($key)) {
 
203            $value = $_SESSION[$key];
204            unset($_SESSION[$key]);
205
206            return $value;
200    public function pull(string $key, mixed $default = null): mixed
201    {
202        if ($this->has($key)) {
 
209        if (func_num_args() > 1) {
 
210            return $default;
200    public function pull(string $key, mixed $default = null): mixed
201    {
202        if ($this->has($key)) {
 
209        if (func_num_args() > 1) {
 
213        throw new OutOfBoundsException(
214            "The session key '{$key}' does not exist",
215        );
216    }
Session->regenerate
261        $this->assertActive();
262
263        if (!session_regenerate_id(true)) {
 
264            throw new RuntimeException('Session id regeneration failed');
261        $this->assertActive();
262
263        if (!session_regenerate_id(true)) {
 
268        $this->csrf->clear();
269    }
Session->remove
238    public function remove(string $key): void
239    {
240        $this->assertActive();
241
242        unset($_SESSION[$key]);
243    }
Session->set
222    public function set(string $key, mixed $value): void
223    {
224        $this->assertActive();
225
226        $_SESSION[$key] = $value;
227    }
Session->start
64        if (session_status() !== PHP_SESSION_NONE) {
 
65            return;
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
88            throw new RuntimeException(
89                'Session handler must implement SessionUpdateTimestampHandlerInterface to support strict mode',
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
88            throw new RuntimeException(
89                'Session handler must implement SessionUpdateTimestampHandlerInterface to support strict mode',
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
88            throw new RuntimeException(
89                'Session handler must implement SessionUpdateTimestampHandlerInterface to support strict mode',
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
88            throw new RuntimeException(
89                'Session handler must implement SessionUpdateTimestampHandlerInterface to support strict mode',
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
79            session_name($this->name);
80        }
81
82        // PHP skips strict mode's id validation without warning when the handler lacks validateId().
83        if (
84            $this->handler
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
88            throw new RuntimeException(
89                'Session handler must implement SessionUpdateTimestampHandlerInterface to support strict mode',
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
88            throw new RuntimeException(
89                'Session handler must implement SessionUpdateTimestampHandlerInterface to support strict mode',
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
88            throw new RuntimeException(
89                'Session handler must implement SessionUpdateTimestampHandlerInterface to support strict mode',
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
88            throw new RuntimeException(
89                'Session handler must implement SessionUpdateTimestampHandlerInterface to support strict mode',
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
94            throw new RuntimeException('Session handler setup failed');
64        if (session_status() !== PHP_SESSION_NONE) {
 
68        if (headers_sent($file, $line)) {
 
78        if ($this->name) {
 
84            $this->handler
 
85            && $this->options['use_strict_mode']
 
86            && !$this->handler instanceof SessionUpdateTimestampHandlerInterface
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
93        if ($this->handler && !session_set_save_handler($this->handler, true)) {
 
97        if (!session_start($this->options)) {
 
102    }