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

Cookie::get()   B

Complexity

Conditions 9
Paths 20

Size

Total Lines 31
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 20
nc 20
nop 2
dl 0
loc 31
rs 8.0555
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 Cookie
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
        // cookie 名称前缀
23
        'prefix'     => '',
24
        // cookie 保存时间
25
        'expire'     => 0,
26
        // cookie 保存路径
27
        'path'       => '/',
28
        // cookie 有效域名
29
        'domain'     => '',
30
        //  cookie 启用安全传输
31
        'secure'     => false,
32
        // httponly设置
33
        'httponly'   => false,
34
        // 是否使用 setcookie
35
        'setcookie'  => true,
36
        // 是否自动写入
37
        'auto_write' => true,
38
    ];
39
40
    /**
41
     * 是否初始化
42
     * @var bool
43
     */
44
    protected $init;
45
46
    /**
47
     * Cookie数据
48
     * @var array
49
     */
50
    protected $data = [];
51
52
    /**
53
     * Cookie写入数据
54
     * @var array
55
     */
56
    protected $cookie = [];
57
58
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $config should have a doc-comment as per coding-style.
Loading history...
59
     * 构造方法
60
     * @access public
61
     */
62
    public function __construct(array $config = [])
63
    {
64
        $this->init($config);
65
    }
66
67
    public static function __make(Config $config)
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
Coding Style introduced by
Method name "Cookie::__make" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
68
    {
69
        return (new static($config->get('cookie')))->setData($_COOKIE);
0 ignored issues
show
Bug introduced by
It seems like $config->get('cookie') can also be of type null; however, parameter $config of think\Cookie::__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

69
        return (new static(/** @scrutinizer ignore-type */ $config->get('cookie')))->setData($_COOKIE);
Loading history...
70
    }
71
72
    /**
73
     * Cookie初始化
74
     * @access public
75
     * @param  array $config
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
76
     * @return void
77
     */
78
    public function init(array $config = []): void
79
    {
80
        $this->config = array_merge($this->config, array_change_key_case($config));
81
82
        if (!empty($this->config['httponly']) && PHP_SESSION_ACTIVE != session_status()) {
83
            ini_set('session.cookie_httponly', '1');
84
        }
85
    }
86
87
    /**
88
     * 设置cookie数据
89
     * @access public
90
     * @param  array $data
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
91
     * @return $this
92
     */
93
    public function setData(array $data)
94
    {
95
        $this->data = $data;
96
        return $this;
97
    }
98
99
    /**
100
     * 获取cookie保存数据
101
     * @access public
102
     * @return array
103
     */
104
    public function getCookie(): array
105
    {
106
        return $this->cookie;
107
    }
108
109
    /**
110
     * 设置或者获取cookie作用域(前缀)
111
     * @access public
112
     * @param  string $prefix
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
113
     * @return string|void
114
     */
115
    public function prefix(string $prefix = '')
116
    {
117
        if (empty($prefix)) {
118
            return $this->config['prefix'];
119
        }
120
121
        $this->config['prefix'] = $prefix;
122
    }
123
124
    /**
125
     * Cookie 设置
126
     *
127
     * @access public
128
     * @param  string               $name  cookie名称
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 2 found
Loading history...
129
     * @param  mixed                $value cookie值
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
130
     * @param  null|integer|array   $option 可选参数 可能会是
131
     * @return void
132
     */
133
    public function set(string $name, $value = '', $option = null): void
134
    {
135
        !isset($this->init) && $this->init();
136
137
        // 参数设置(会覆盖黙认设置)
138
        if (!is_null($option)) {
139
            if (is_numeric($option)) {
140
                $option = ['expire' => $option];
141
            }
142
143
            $config = array_merge($this->config, array_change_key_case($option));
144
        } else {
145
            $config = $this->config;
146
        }
147
148
        $name = $config['prefix'] . $name;
149
150
        // 设置cookie
151
        if (is_array($value)) {
152
            array_walk_recursive($value, [$this, 'jsonFormatProtect'], 'encode');
153
            $value = 'think:' . json_encode($value);
154
        }
155
156
        $expire = !empty($config['expire']) ? $_SERVER['REQUEST_TIME'] + intval($config['expire']) : 0;
157
158
        $this->data[$name] = $value;
159
160
        $this->setCookie($name, (string) $value, $expire, $config);
161
    }
162
163
    /**
164
     * Cookie 保存
165
     *
166
     * @access public
167
     * @param  string $name  cookie名称
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 2 found
Loading history...
168
     * @param  mixed  $value cookie值
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
169
     * @param  int    $expire 有效期
170
     * @param  array  $option 可选参数
171
     * @return void
172
     */
173
    protected function setCookie(string $name, string $value, int $expire, array $option = []): void
174
    {
175
        $this->cookie[$name] = [$value, $expire, $option];
176
    }
177
178
    /**
179
     * 永久保存Cookie数据
180
     * @access public
181
     * @param  string $name  cookie名称
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 2 found
Loading history...
182
     * @param  mixed  $value cookie值
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
183
     * @param  mixed  $option 可选参数 可能会是 null|integer|string
184
     * @return void
185
     */
186
    public function forever(string $name, $value = '', $option = null): void
187
    {
188
        if (is_null($option) || is_numeric($option)) {
189
            $option = [];
190
        }
191
192
        $option['expire'] = 315360000;
193
194
        $this->set($name, $value, $option);
195
    }
196
197
    /**
198
     * 判断Cookie数据
199
     * @access public
200
     * @param  string        $name cookie名称
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
201
     * @param  string|null   $prefix cookie前缀
202
     * @return bool
203
     */
204
    public function has(string $name, string $prefix = null): bool
205
    {
206
        !isset($this->init) && $this->init();
207
208
        $prefix = !is_null($prefix) ? $prefix : $this->config['prefix'];
209
        $name   = $prefix . $name;
210
211
        return isset($this->data[$name]);
212
    }
213
214
    /**
215
     * Cookie获取
216
     * @access public
217
     * @param  string        $name cookie名称 留空获取全部
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
218
     * @param  string|null   $prefix cookie前缀
219
     * @return mixed
220
     */
221
    public function get(string $name = '', string $prefix = null)
222
    {
223
        !isset($this->init) && $this->init();
224
225
        $prefix = !is_null($prefix) ? $prefix : $this->config['prefix'];
226
        $key    = $prefix . $name;
227
228
        if ('' == $name) {
229
            if ($prefix) {
230
                $value = [];
231
                foreach ($this->data as $k => $val) {
232
                    if (0 === strpos($k, $prefix)) {
233
                        $value[$k] = $val;
234
                    }
235
                }
236
            } else {
237
                $value = $this->data;
238
            }
239
        } elseif (isset($this->data[$key])) {
240
            $value = $this->data[$key];
241
242
            if (0 === strpos($value, 'think:')) {
243
                $value = substr($value, 6);
244
                $value = json_decode($value, true);
245
                array_walk_recursive($value, [$this, 'jsonFormatProtect'], 'decode');
246
            }
247
        } else {
248
            $value = null;
249
        }
250
251
        return $value;
252
    }
253
254
    /**
255
     * Cookie删除
256
     * @access public
257
     * @param  string        $name cookie名称
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
258
     * @param  string|null   $prefix cookie前缀
259
     * @return void
260
     */
261
    public function delete(string $name, string $prefix = null): void
262
    {
263
        !isset($this->init) && $this->init();
264
265
        $config = $this->config;
266
        $prefix = !is_null($prefix) ? $prefix : $config['prefix'];
267
        $name   = $prefix . $name;
268
269
        $this->setCookie($name, '', $_SERVER['REQUEST_TIME'] - 3600, $config);
270
271
        // 删除指定cookie
272
        unset($this->data[$name]);
273
    }
274
275
    /**
276
     * Cookie清空
277
     * @access public
278
     * @param  string|null $prefix cookie前缀
279
     * @return void
280
     */
281
    public function clear(string $prefix = null): void
282
    {
283
        // 清除指定前缀的所有cookie
284
        if (empty($this->data)) {
285
            return;
286
        }
287
288
        !isset($this->init) && $this->init();
289
290
        // 要删除的cookie前缀,不指定则删除config设置的指定前缀
291
        $config = $this->config;
292
        $prefix = !is_null($prefix) ? $prefix : $config['prefix'];
293
294
        if ($prefix) {
295
            // 如果前缀为空字符串将不作处理直接返回
296
            foreach ($this->data as $key => $val) {
297
                if (0 === strpos($key, $prefix)) {
298
                    $this->setCookie($key, '', $_SERVER['REQUEST_TIME'] - 3600, $config);
299
                    unset($this->data[$key]);
300
                }
301
            }
302
        }
303
304
        return;
305
    }
306
307
    private function jsonFormatProtect(&$val, $key, $type = 'encode'): void
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
Coding Style introduced by
Private method name "Cookie::jsonFormatProtect" must be prefixed with an underscore
Loading history...
308
    {
309
        if (!empty($val) && true !== $val) {
310
            $val = 'decode' == $type ? urldecode($val) : urlencode((string) $val);
311
        }
312
    }
313
314
    public function save(): void
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
315
    {
316
        foreach ($this->cookie as $name => $val) {
317
            list($value, $expire, $option) = $val;
318
            setcookie($name, $value, $expire, $option['path'], $option['domain'], $option['secure'] ? true : false, $option['httponly'] ? true : false);
319
        }
320
    }
321
322
}
323