Passed
Push — 8.0 ( 55dae4...75c977 )
by liu
11:29 queued 08:57
created

Store   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 307
Duplicated Lines 0 %

Test Coverage

Coverage 91.78%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 57
c 1
b 0
f 0
dl 0
loc 307
ccs 67
cts 73
cp 0.9178
rs 9.92
wmc 31

23 Methods

Rating   Name   Duplication   Size   Complexity  
A set() 0 3 1
A setData() 0 3 1
A init() 0 10 2
A getName() 0 3 1
A all() 0 3 1
A getId() 0 3 1
A __construct() 0 7 2
A get() 0 3 1
A setId() 0 3 4
A setName() 0 3 1
A flash() 0 5 1
A serialize() 0 5 1
A pull() 0 3 1
A save() 0 15 2
A clear() 0 3 1
A delete() 0 3 1
A clearFlashData() 0 9 2
A has() 0 3 1
A reflash() 0 6 1
A unserialize() 0 5 1
A destroy() 0 5 1
A regenerate() 0 7 2
A push() 0 7 1
1
<?php
2
// +----------------------------------------------------------------------
3
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
6
// +----------------------------------------------------------------------
7
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
8
// +----------------------------------------------------------------------
9
// | Author: yunwuxin <[email protected]>
10
// +----------------------------------------------------------------------
11
12
namespace think\session;
13
14
use think\contract\SessionHandlerInterface;
15
use think\helper\Arr;
16
17
class Store
18
{
19
    /**
20
     * Session数据
21
     * @var array
22
     */
23
    protected $data = [];
24
25
    /**
26
     * 是否初始化
27
     * @var bool
28
     */
29
    protected $init = null;
30
31
    /**
32
     * 记录Session Id
33
     * @var string
34
     */
35
    protected $id;
36
37
    /** @var array */
38
    protected $serialize = [];
39
40 18
    public function __construct(protected string $name, protected SessionHandlerInterface $handler, array $serialize = null)
41
    {
42 18
        if (!empty($serialize)) {
43
            $this->serialize = $serialize;
44
        }
45
46 18
        $this->setId();
47
    }
48
49
    /**
50
     * 设置数据
51
     * @access public
52
     * @param array $data
53
     * @return void
54
     */
55
    public function setData(array $data): void
56
    {
57
        $this->data = $data;
58
    }
59
60
    /**
61
     * session初始化
62
     * @access public
63
     * @return void
64
     */
65 9
    public function init(): void
66
    {
67
        // 读取缓存数据
68 9
        $data = $this->handler->read($this->getId());
69
70 9
        if (!empty($data)) {
71 3
            $this->data = array_merge($this->data, $this->unserialize($data));
72
        }
73
74 9
        $this->init = true;
75
    }
76
77
    /**
78
     * 设置SessionName
79
     * @access public
80
     * @param string $name session_name
81
     * @return void
82
     */
83 3
    public function setName(string $name): void
84
    {
85 3
        $this->name = $name;
86
    }
87
88
    /**
89
     * 获取sessionName
90
     * @access public
91
     * @return string
92
     */
93 3
    public function getName(): string
94
    {
95 3
        return $this->name;
96
    }
97
98
    /**
99
     * session_id设置
100
     * @access public
101
     * @param string $id session_id
102
     * @return void
103
     */
104 18
    public function setId(string $id = null): void
105
    {
106 18
        $this->id = is_string($id) && strlen($id) === 32 && ctype_alnum($id) ? $id : md5(microtime(true) . session_create_id());
107
    }
108
109
    /**
110
     * 获取session_id
111
     * @access public
112
     * @return string
113
     */
114 9
    public function getId(): string
115
    {
116 9
        return $this->id;
117
    }
118
119
    /**
120
     * 获取所有数据
121
     * @return array
122
     */
123
    public function all(): array
124
    {
125
        return $this->data;
126
    }
127
128
    /**
129
     * session设置
130
     * @access public
131
     * @param string $name  session名称
132
     * @param mixed  $value session值
133
     * @return void
134
     */
135 15
    public function set(string $name, $value): void
136
    {
137 15
        Arr::set($this->data, $name, $value);
138
    }
139
140
    /**
141
     * session获取
142
     * @access public
143
     * @param string $name    session名称
144
     * @param mixed  $default 默认值
145
     * @return mixed
146
     */
147 12
    public function get(string $name, $default = null)
148
    {
149 12
        return Arr::get($this->data, $name, $default);
150
    }
151
152
    /**
153
     * session获取并删除
154
     * @access public
155
     * @param string $name session名称
156
     * @param mixed  $default 默认值
157
     * @return mixed
158
     */
159 3
    public function pull(string $name, $default = null)
160
    {
161 3
        return Arr::pull($this->data, $name, $default);
162
    }
163
164
    /**
165
     * 添加数据到一个session数组
166
     * @access public
167
     * @param string $key
168
     * @param mixed  $value
169
     * @return void
170
     */
171 3
    public function push(string $key, $value): void
172
    {
173 3
        $array = $this->get($key, []);
174
175 3
        $array[] = $value;
176
177 3
        $this->set($key, $array);
178
    }
179
180
    /**
181
     * 判断session数据
182
     * @access public
183
     * @param string $name session名称
184
     * @return bool
185
     */
186 12
    public function has(string $name): bool
187
    {
188 12
        return Arr::has($this->data, $name);
189
    }
190
191
    /**
192
     * 删除session数据
193
     * @access public
194
     * @param string $name session名称
195
     * @return void
196
     */
197 6
    public function delete(string $name): void
198
    {
199 6
        Arr::forget($this->data, $name);
200
    }
201
202
    /**
203
     * 清空session数据
204
     * @access public
205
     * @return void
206
     */
207 6
    public function clear(): void
208
    {
209 6
        $this->data = [];
210
    }
211
212
    /**
213
     * 销毁session
214
     */
215 3
    public function destroy(): void
216
    {
217 3
        $this->clear();
218
219 3
        $this->regenerate(true);
220
    }
221
222
    /**
223
     * 重新生成session id
224
     * @param bool $destroy
225
     */
226 3
    public function regenerate(bool $destroy = false): void
227
    {
228 3
        if ($destroy) {
229 3
            $this->handler->delete($this->getId());
230
        }
231
232 3
        $this->setId();
233
    }
234
235
    /**
236
     * 保存session数据
237
     * @access public
238
     * @return void
239
     */
240 3
    public function save(): void
241
    {
242 3
        $this->clearFlashData();
243
244 3
        $sessionId = $this->getId();
245
246 3
        if (!empty($this->data)) {
247 3
            $data = $this->serialize($this->data);
248
249 3
            $this->handler->write($sessionId, $data);
250
        } else {
251
            $this->handler->delete($sessionId);
252
        }
253
254 3
        $this->init = false;
255
    }
256
257
    /**
258
     * session设置 下一次请求有效
259
     * @access public
260
     * @param string $name  session名称
261
     * @param mixed  $value session值
262
     * @return void
263
     */
264 3
    public function flash(string $name, $value): void
265
    {
266 3
        $this->set($name, $value);
267 3
        $this->push('__flash__.__next__', $name);
268 3
        $this->set('__flash__.__current__', Arr::except($this->get('__flash__.__current__', []), $name));
0 ignored issues
show
Bug introduced by
It seems like $this->get('__flash__.__current__', array()) can also be of type TValue; however, parameter $array of think\helper\Arr::except() 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

268
        $this->set('__flash__.__current__', Arr::except(/** @scrutinizer ignore-type */ $this->get('__flash__.__current__', []), $name));
Loading history...
269
    }
270
271
    /**
272
     * 将本次闪存数据推迟到下次请求
273
     *
274
     * @return void
275
     */
276 3
    public function reflash(): void
277
    {
278 3
        $keys   = $this->get('__flash__.__current__', []);
279 3
        $values = array_unique(array_merge($this->get('__flash__.__next__', []), $keys));
0 ignored issues
show
Bug introduced by
It seems like $this->get('__flash__.__next__', array()) can also be of type TValue; however, parameter $arrays of array_merge() 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

279
        $values = array_unique(array_merge(/** @scrutinizer ignore-type */ $this->get('__flash__.__next__', []), $keys));
Loading history...
280 3
        $this->set('__flash__.__next__', $values);
281 3
        $this->set('__flash__.__current__', []);
282
    }
283
284
    /**
285
     * 清空当前请求的session数据
286
     * @access public
287
     * @return void
288
     */
289 6
    public function clearFlashData(): void
290
    {
291 6
        Arr::forget($this->data, $this->get('__flash__.__current__', []));
292 6
        if (!empty($next = $this->get('__flash__.__next__', []))) {
293 3
            $this->set('__flash__.__current__', $next);
294
        } else {
295 6
            $this->delete('__flash__.__current__');
296
        }
297 6
        $this->delete('__flash__.__next__');
298
    }
299
300
    /**
301
     * 序列化数据
302
     * @access protected
303
     * @param mixed $data
304
     * @return string
305
     */
306 3
    protected function serialize($data): string
307
    {
308 3
        $serialize = $this->serialize[0] ?? 'serialize';
309
310 3
        return $serialize($data);
311
    }
312
313
    /**
314
     * 反序列化数据
315
     * @access protected
316
     * @param string $data
317
     * @return array
318
     */
319 3
    protected function unserialize(string $data): array
320
    {
321 3
        $unserialize = $this->serialize[1] ?? 'unserialize';
322
323 3
        return (array) $unserialize($data);
324
    }
325
}
326