Passed
Push — 6.0 ( 134599...707bea )
by liu
03:59
created

Session::pause()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
// +----------------------------------------------------------------------
1 ignored issue
show
Coding Style introduced by
You must use "/**" style comments for a file comment
Loading history...
3
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
6
// +----------------------------------------------------------------------
7
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
8
// +----------------------------------------------------------------------
9
// | Author: liu21st <[email protected]>
10
// +----------------------------------------------------------------------
11
declare (strict_types = 1);
12
13
namespace think;
14
15
class Session
1 ignored issue
show
Coding Style introduced by
Missing class doc comment
Loading history...
16
{
17
    /**
18
     * 配置参数
19
     * @var array
20
     */
21
    protected $config = [];
22
23
    /**
24
     * Session数据
25
     * @var array
26
     */
27
    protected $data = [];
28
29
    /**
30
     * 是否初始化
31
     * @var bool
32
     */
33
    protected $init = null;
34
35
    /**
36
     * 记录Session name
37
     * @var string
38
     */
39
    protected $sessionName = 'PHPSESSID';
40
41
    /**
42
     * 记录Session Id
43
     * @var string
44
     */
45
    protected $sessionId;
46
47
    /**
48
     * Session有效期
49
     * @var int
50
     */
51
    protected $expire = 0;
52
53
    /**
54
     * App实例
55
     * @var App
56
     */
57
    protected $app;
58
59
    /**
60
     * Session写入对象
61
     * @var object
62
     */
63
    protected $handler;
64
65
    public function __construct(App $app, array $config = [])
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
66
    {
67
        $this->config = $config;
68
        $this->app    = $app;
69
    }
70
71
    public static function __make(App $app, Config $config)
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
Coding Style introduced by
Method name "Session::__make" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
72
    {
73
        return new static($app, $config->get('session'));
0 ignored issues
show
Bug introduced by
It seems like $config->get('session') can also be of type null; however, parameter $config of think\Session::__construct() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

73
        return new static($app, /** @scrutinizer ignore-type */ $config->get('session'));
Loading history...
74
    }
75
76
    /**
77
     * 配置
78
     * @access public
79
     * @param  array $config
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
80
     * @return void
81
     */
82
    public function setConfig(array $config = []): void
83
    {
84
        $this->config = array_merge($this->config, array_change_key_case($config));
85
    }
86
87
    /**
88
     * 设置数据
89
     * @access public
90
     * @param  array $data
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
91
     * @return void
92
     */
93
    public function setData(array $data): void
94
    {
95
        $this->data = $data;
96
    }
97
98
    /**
99
     * session初始化
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
100
     * @access public
101
     * @return void
102
     * @throws \think\Exception
103
     */
104
    public function init(): void
105
    {
106
        if (!empty($this->config['name'])) {
107
            $this->sessionName = $this->config['name'];
108
        }
109
110
        if (!empty($this->config['expire'])) {
111
            $this->expire = $this->config['expire'];
112
        }
113
114
        // 初始化session写入驱动
115
        $type = !empty($this->config['type']) ? $this->config['type'] : 'File';
116
117
        $this->handler = $this->app->factory($type, '\\think\\session\\driver\\', $this->config);
118
119
        if (!empty($this->config['auto_start'])) {
120
            $this->start();
121
        } else {
122
            $this->init = false;
123
        }
124
    }
125
126
    /**
127
     * session自动启动或者初始化
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
128
     * @access public
129
     * @return void
130
     */
131
    public function boot(): void
132
    {
133
        if (is_null($this->init)) {
0 ignored issues
show
introduced by
The condition is_null($this->init) is always false.
Loading history...
134
            $this->init();
135
        }
136
137
        if (false === $this->init) {
138
            $this->start();
139
        }
140
    }
141
142
    public function setName(string $name): void
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
143
    {
144
        $this->sessionName = $name;
145
    }
146
147
    public function getName(): string
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
148
    {
149
        return $this->sessionName;
150
    }
151
152
    /**
153
     * session_id设置
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
154
     * @access public
155
     * @param  string $id session_id
156
     * @return void
157
     */
158
    public function setId(string $id): void
159
    {
160
        $this->sessionId = $id;
161
    }
162
163
    /**
164
     * 获取session_id
165
     * @access public
166
     * @param  bool $regenerate 不存在是否自动生成
167
     * @return string
168
     */
169
    public function getId(bool $regenerate = true): string
170
    {
171
        if ($this->sessionId) {
172
            return $this->sessionId;
173
        }
174
175
        return $regenerate ? $this->regenerate() : '';
176
    }
177
178
    /**
179
     * session设置
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
180
     * @access public
181
     * @param  string $name session名称
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
182
     * @param  mixed  $value session值
183
     * @return void
184
     */
185
    public function set(string $name, $value): void
186
    {
187
        empty($this->init) && $this->boot();
188
189
        if (strpos($name, '.')) {
190
            // 二维数组赋值
191
            list($name1, $name2) = explode('.', $name);
192
193
            $this->data[$name1][$name2] = $value;
194
        } else {
195
            $this->data[$name] = $value;
196
        }
197
    }
198
199
    /**
200
     * session获取
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
201
     * @access public
202
     * @param  string $name session名称
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
203
     * @param  mixed  $default 默认值
204
     * @return mixed
205
     */
206
    public function get(string $name = '', $default = null)
207
    {
208
        empty($this->init) && $this->boot();
209
210
        $sessionId = $this->getId();
211
212
        return $this->readSession($sessionId, $name, $default);
213
    }
214
215
    /**
216
     * session获取
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
217
     * @access protected
218
     * @param  string $sessionId session_id
219
     * @param  string $name session名称
0 ignored issues
show
Coding Style introduced by
Expected 6 spaces after parameter name; 1 found
Loading history...
220
     * @param  mixed  $default 默认值
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
221
     * @return mixed
222
     */
223
    protected function readSession(string $sessionId, string $name = '', $default = null)
0 ignored issues
show
Unused Code introduced by
The parameter $sessionId is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

223
    protected function readSession(/** @scrutinizer ignore-unused */ string $sessionId, string $name = '', $default = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
224
    {
225
        $value = $this->data;
226
227
        if ('' != $name) {
228
            $name = explode('.', $name);
229
230
            foreach ($name as $val) {
231
                if (isset($value[$val])) {
232
                    $value = $value[$val];
233
                } else {
234
                    $value = $default;
235
                    break;
236
                }
237
            }
238
        }
239
240
        return $value;
241
    }
242
243
    /**
244
     * 删除session数据
245
     * @access public
246
     * @param  string|array $name session名称
247
     * @return void
248
     */
249
    public function delete($name): bool
250
    {
251
        empty($this->init) && $this->boot();
252
253
        $sessionId = $this->getId(false);
254
255
        if (!$sessionId) {
256
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type void.
Loading history...
257
        }
258
259
        if (is_array($name)) {
260
            foreach ($name as $key) {
261
                $this->deleteSession($sessionId, $key);
0 ignored issues
show
Bug introduced by
The method deleteSession() does not exist on think\Session. Did you maybe mean delete()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

261
                $this->/** @scrutinizer ignore-call */ 
262
                       deleteSession($sessionId, $key);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
262
            }
263
        } elseif (strpos($name, '.')) {
264
            list($name1, $name2) = explode('.', $name);
265
            unset($this->data[$name1][$name2]);
266
        } else {
267
            unset($this->data[$name]);
268
        }
269
270
        return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the documented return type void.
Loading history...
271
    }
272
273
    /**
274
     * 保存session数据
275
     * @access public
276
     * @return void
277
     */
278
    public function save()
279
    {
280
        if ($this->handler) {
281
            $sessionId = $this->getId(false);
282
283
            if (!empty($this->data)) {
284
                $data = $this->serialize($this->data);
285
286
                $this->handler->write($sessionId, $data, $this->expire);
287
            } else {
288
                $this->handler->delete($sessionId);
289
            }
290
        }
291
292
    }
293
294
    /**
295
     * 清空session数据
296
     * @access public
297
     * @return void
298
     */
299
    public function clear(): void
300
    {
301
        empty($this->init) && $this->boot();
302
303
        $sessionId = $this->getId(false);
304
305
        if ($sessionId) {
306
            $this->data = [];
307
        }
308
    }
309
310
    /**
311
     * 判断session数据
312
     * @access public
313
     * @param  string $name session名称
314
     * @return bool
315
     */
316
    public function has(string $name): bool
317
    {
318
        empty($this->init) && $this->boot();
319
320
        $sessionId = $this->getId(false);
321
322
        if ($sessionId) {
323
            return $this->hasSession($sessionId, $name);
324
        }
325
326
        return false;
327
    }
328
329
    /**
330
     * 判断session数据
331
     * @access protected
332
     * @param  string $sessionId session_id
333
     * @param  string $name session名称
0 ignored issues
show
Coding Style introduced by
Expected 6 spaces after parameter name; 1 found
Loading history...
334
     * @return bool
335
     */
336
    protected function hasSession(string $sessionId, string $name): bool
0 ignored issues
show
Unused Code introduced by
The parameter $sessionId is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

336
    protected function hasSession(/** @scrutinizer ignore-unused */ string $sessionId, string $name): bool

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
337
    {
338
        $value = $this->data ?: [];
339
340
        $name = explode('.', $name);
341
342
        foreach ($name as $val) {
343
            if (!isset($value[$val])) {
344
                return false;
345
            } else {
346
                $value = $value[$val];
347
            }
348
        }
349
350
        return true;
351
    }
352
353
    /**
354
     * 启动session
355
     * @access public
356
     * @return void
357
     */
358
    public function start(): void
359
    {
360
        $sessionId = $this->getId();
361
362
        // 读取缓存数据
363
        if (empty($this->data)) {
364
            $data = $this->handler->read($sessionId);
365
366
            if (!empty($data)) {
367
                $this->data = $this->unserialize($data);
368
            }
369
        }
370
371
        $this->init = true;
372
    }
373
374
    /**
375
     * 销毁session
376
     * @access public
377
     * @return void
378
     */
379
    public function destroy(): void
380
    {
381
        $sessionId = $this->getId(false);
382
383
        if ($sessionId && !empty($this->data)) {
384
            $this->data = [];
385
            $this->save();
386
        }
387
    }
388
389
    /**
390
     * 生成session_id
391
     * @access protected
392
     * @param  bool $delete 是否删除关联会话文件
393
     * @return string
394
     */
395
    protected function regenerate(bool $delete = false): string
396
    {
397
        if ($delete) {
398
            $this->destroy();
399
        }
400
401
        $sessionId = md5(microtime(true) . uniqid());
402
403
        $this->sessionId = $sessionId;
404
        return $sessionId;
405
    }
406
407
    /**
408
     * session获取并删除
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
409
     * @access public
410
     * @param  string $name session名称
411
     * @return mixed
412
     */
413
    public function pull(string $name)
414
    {
415
        $result = $this->get($name);
416
417
        if ($result) {
418
            $this->delete($name);
419
            return $result;
420
        }
421
    }
422
423
    /**
424
     * session设置 下一次请求有效
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
425
     * @access public
426
     * @param  string $name session名称
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
427
     * @param  mixed  $value session值
428
     * @return void
429
     */
430
    public function flash(string $name, $value): void
431
    {
432
        $this->set($name, $value);
433
434
        if (!$this->has('__flash__.__time__')) {
435
            $this->set('__flash__.__time__', $this->app->request->time(true));
436
        }
437
438
        $this->push('__flash__', $name);
439
    }
440
441
    /**
442
     * 清空当前请求的session数据
443
     * @access public
444
     * @return void
445
     */
446
    public function flush()
447
    {
448
        if (!$this->init) {
449
            return;
450
        }
451
452
        $item = $this->get('__flash__');
453
454
        if (!empty($item)) {
455
            $time = $item['__time__'];
456
457
            if ($this->app->request->time(true) > $time) {
458
                unset($item['__time__']);
459
                $this->delete($item);
460
                $this->set('__flash__', []);
461
            }
462
        }
463
    }
464
465
    /**
466
     * 添加数据到一个session数组
467
     * @access public
468
     * @param  string $key
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
469
     * @param  mixed  $value
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
470
     * @return void
471
     */
472
    public function push(string $key, $value): void
473
    {
474
        $array = $this->get($key);
475
476
        if (is_null($array)) {
477
            $array = [];
478
        }
479
480
        $array[] = $value;
481
482
        $this->set($key, $array);
483
    }
484
485
    /**
486
     * 序列化数据
487
     * @access protected
488
     * @param  mixed $data
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
489
     * @return string
490
     */
491
    protected function serialize($data): string
492
    {
493
        $serialize = $this->config['serialize'][0] ?? 'serialize';
494
495
        return $serialize($data);
496
    }
497
498
    /**
499
     * 反序列化数据
500
     * @access protected
501
     * @param  string $data
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
502
     * @return mixed
503
     */
504
    protected function unserialize(string $data)
505
    {
506
        $unserialize = $this->config['serialize'][1] ?? 'unserialize';
507
508
        return $unserialize($data);
509
    }
510
}
511