Passed
Push — 6.0 ( f409e2...e26961 )
by liu
02:35
created

Session::hasSession()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 2
dl 0
loc 15
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['option'] ?? []);
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
        $sessionId = $this->getId();
190
191
        if (strpos($name, '.')) {
192
            // 二维数组赋值
193
            list($name1, $name2) = explode('.', $name);
194
195
            $this->data[$sessionId][$name1][$name2] = $value;
196
        } else {
197
            $this->data[$sessionId][$name] = $value;
198
        }
199
    }
200
201
    /**
202
     * session获取
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
203
     * @access public
204
     * @param  string $name session名称
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
205
     * @param  mixed  $default 默认值
206
     * @return mixed
207
     */
208
    public function get(string $name = '', $default = null)
209
    {
210
        empty($this->init) && $this->boot();
211
212
        $sessionId = $this->getId();
213
214
        return $this->readSession($sessionId, $name, $default);
215
    }
216
217
    /**
218
     * session获取
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
219
     * @access protected
220
     * @param  string $sessionId session_id
221
     * @param  string $name session名称
0 ignored issues
show
Coding Style introduced by
Expected 6 spaces after parameter name; 1 found
Loading history...
222
     * @param  mixed  $default 默认值
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
223
     * @return mixed
224
     */
225
    protected function readSession(string $sessionId, string $name = '', $default = null)
226
    {
227
        $value = $this->data[$sessionId] ?? [];
228
229
        if (!is_array($value)) {
230
            $value = [];
231
        }
232
233
        if ('' != $name) {
234
            $name = explode('.', $name);
235
236
            foreach ($name as $val) {
237
                if (isset($value[$val])) {
238
                    $value = $value[$val];
239
                } else {
240
                    $value = $default;
241
                    break;
242
                }
243
            }
244
        }
245
246
        return $value;
247
    }
248
249
    /**
250
     * 删除session数据
251
     * @access public
252
     * @param  string|array $name session名称
253
     * @return void
254
     */
255
    public function delete($name): bool
256
    {
257
        empty($this->init) && $this->boot();
258
259
        $sessionId = $this->getId(false);
260
261
        if (!$sessionId) {
262
            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...
263
        }
264
265
        if (is_array($name)) {
266
            foreach ($name as $key) {
267
                $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

267
                $this->/** @scrutinizer ignore-call */ 
268
                       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...
268
            }
269
        } elseif (strpos($name, '.')) {
270
            list($name1, $name2) = explode('.', $name);
271
            unset($this->data[$sessionId][$name1][$name2]);
272
        } else {
273
            unset($this->data[$sessionId][$name]);
274
        }
275
276
        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...
277
    }
278
279
    /**
280
     * 保存session数据
281
     * @access public
282
     * @return void
283
     */
284
    public function save()
285
    {
286
        $sessionId = $this->getId(false);
287
288
        if (!empty($this->data[$sessionId])) {
289
            $this->handler->write($sessionId, $this->data[$sessionId], $this->expire);
290
        } else {
291
            $this->handler->delete($sessionId);
292
        }
293
    }
294
295
    /**
296
     * 清空session数据
297
     * @access public
298
     * @return void
299
     */
300
    public function clear(): void
301
    {
302
        empty($this->init) && $this->boot();
303
304
        $sessionId = $this->getId(false);
305
306
        if ($sessionId) {
307
            $this->data[$sessionId] = [];
308
        }
309
    }
310
311
    /**
312
     * 判断session数据
313
     * @access public
314
     * @param  string $name session名称
315
     * @return bool
316
     */
317
    public function has(string $name): bool
318
    {
319
        empty($this->init) && $this->boot();
320
321
        $sessionId = $this->getId(false);
322
323
        if ($sessionId) {
324
            return $this->hasSession($sessionId, $name);
325
        }
326
327
        return false;
328
    }
329
330
    /**
331
     * 判断session数据
332
     * @access protected
333
     * @param  string $sessionId session_id
334
     * @param  string $name session名称
0 ignored issues
show
Coding Style introduced by
Expected 6 spaces after parameter name; 1 found
Loading history...
335
     * @return bool
336
     */
337
    protected function hasSession(string $sessionId, string $name): bool
338
    {
339
        $value = $this->data[$sessionId] ?? [];
340
341
        $name = explode('.', $name);
342
343
        foreach ($name as $val) {
344
            if (!isset($value[$val])) {
345
                return false;
346
            } else {
347
                $value = $value[$val];
348
            }
349
        }
350
351
        return true;
352
    }
353
354
    /**
355
     * 启动session
356
     * @access public
357
     * @return void
358
     */
359
    public function start(): void
360
    {
361
        $sessionId = $this->getId();
362
363
        // 读取缓存数据
364
        if (empty($this->data[$sessionId])) {
365
            $data = $this->handler->read($sessionId);
366
367
            if (!empty($data)) {
368
                $this->data[$sessionId] = $data;
369
            }
370
        }
371
372
        $this->init = true;
373
    }
374
375
    /**
376
     * 销毁session
377
     * @access public
378
     * @return void
379
     */
380
    public function destroy(): void
381
    {
382
        $sessionId = $this->getId(false);
383
384
        if ($sessionId && isset($this->data[$sessionId])) {
385
            unset($this->data[$sessionId]);
386
        }
387
388
        $this->init = null;
389
    }
390
391
    /**
392
     * 生成session_id
393
     * @access public
394
     * @param  bool $delete 是否删除关联会话文件
395
     * @return string
396
     */
397
    public function regenerate(bool $delete = false): string
398
    {
399
        if ($delete) {
400
            $this->destroy();
401
        }
402
403
        $sessionId = md5(microtime(true) . uniqid());
404
405
        $this->sessionId = $sessionId;
406
        return $sessionId;
407
    }
408
409
    /**
410
     * 暂停session
411
     * @access public
412
     * @return void
413
     */
414
    public function pause(): void
415
    {
416
        $this->init = false;
417
    }
418
419
    /**
420
     * session获取并删除
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
421
     * @access public
422
     * @param  string $name session名称
423
     * @return mixed
424
     */
425
    public function pull(string $name)
426
    {
427
        $result = $this->get($name);
428
429
        if ($result) {
430
            $this->delete($name);
431
            return $result;
432
        }
433
    }
434
435
    /**
436
     * session设置 下一次请求有效
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
437
     * @access public
438
     * @param  string $name session名称
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
439
     * @param  mixed  $value session值
440
     * @return void
441
     */
442
    public function flash(string $name, $value): void
443
    {
444
        $this->set($name, $value);
445
446
        if (!$this->has('__flash__.__time__')) {
447
            $this->set('__flash__.__time__', $this->app->request->time(true));
448
        }
449
450
        $this->push('__flash__', $name);
451
    }
452
453
    /**
454
     * 清空当前请求的session数据
455
     * @access public
456
     * @return void
457
     */
458
    public function flush()
459
    {
460
        if (!$this->init) {
461
            return;
462
        }
463
464
        $item = $this->get('__flash__');
465
466
        if (!empty($item)) {
467
            $time = $item['__time__'];
468
469
            if ($this->app->request->time(true) > $time) {
470
                unset($item['__time__']);
471
                $this->delete($item);
472
                $this->set('__flash__', []);
473
            }
474
        }
475
    }
476
477
    /**
478
     * 添加数据到一个session数组
479
     * @access public
480
     * @param  string $key
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
481
     * @param  mixed  $value
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
482
     * @return void
483
     */
484
    public function push(string $key, $value): void
485
    {
486
        $array = $this->get($key);
487
488
        if (is_null($array)) {
489
            $array = [];
490
        }
491
492
        $array[] = $value;
493
494
        $this->set($key, $array);
495
    }
496
497
}
498