Passed
Push — 5.2 ( ead1b1...98d507 )
by liu
02:32
created

Request::panDomain()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
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
use think\facade\Cookie;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, think\Cookie. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
16
use think\facade\Session;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, think\Session. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
17
use think\route\Dispatch;
18
19
class Request
1 ignored issue
show
Coding Style introduced by
Missing class doc comment
Loading history...
20
{
21
    /**
22
     * 配置
23
     * @var array
24
     */
25
    protected $config = [
26
        // PATHINFO变量名 用于兼容模式
27
        'var_pathinfo'           => 's',
28
        // 兼容PATH_INFO获取
29
        'pathinfo_fetch'         => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
30
        // 表单请求类型伪装变量
31
        'var_method'             => '_method',
32
        // 表单ajax伪装变量
33
        'var_ajax'               => '_ajax',
34
        // 表单pjax伪装变量
35
        'var_pjax'               => '_pjax',
36
        // 默认全局过滤方法 用逗号分隔多个
37
        'default_filter'         => '',
38
        // 域名根,如thinkphp.cn
39
        'url_domain_root'        => '',
40
        // HTTPS代理标识
41
        'https_agent_name'       => '',
42
        // 前端代理服务器IP
43
        'proxy_server_ip'        => [],
44
        // 前端代理服务器真实IP头
45
        'proxy_server_ip_header' => ['HTTP_X_REAL_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP'],
46
        // URL伪静态后缀
47
        'url_html_suffix'        => 'html',
48
        // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
49
        'request_cache'          => false,
50
        // 请求缓存有效期
51
        'request_cache_expire'   => null,
52
        // 全局请求缓存排除规则
53
        'request_cache_except'   => [],
54
        // 请求缓存的Tag
55
        'request_cache_tag'      => '',
56
    ];
57
58
    /**
59
     * 请求类型
60
     * @var string
61
     */
62
    protected $method;
63
64
    /**
65
     * 域名(含协议及端口)
66
     * @var string
67
     */
68
    protected $domain;
69
70
    /**
71
     * HOST(含端口)
72
     * @var string
73
     */
74
    protected $host;
75
76
    /**
77
     * 子域名
78
     * @var string
79
     */
80
    protected $subDomain;
81
82
    /**
83
     * 泛域名
84
     * @var string
85
     */
86
    protected $panDomain;
87
88
    /**
89
     * 当前URL地址
90
     * @var string
91
     */
92
    protected $url;
93
94
    /**
95
     * 基础URL
96
     * @var string
97
     */
98
    protected $baseUrl;
99
100
    /**
101
     * 当前执行的文件
102
     * @var string
103
     */
104
    protected $baseFile;
105
106
    /**
107
     * 访问的ROOT地址
108
     * @var string
109
     */
110
    protected $root;
111
112
    /**
113
     * pathinfo
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
114
     * @var string
115
     */
116
    protected $pathinfo;
117
118
    /**
119
     * pathinfo(不含后缀)
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
120
     * @var string
121
     */
122
    protected $path;
123
124
    /**
125
     * 当前请求的IP地址
126
     * @var string
127
     */
128
    protected $realIP;
129
130
    /**
131
     * 当前路由信息
132
     * @var array
133
     */
134
    protected $routeInfo = [];
135
136
    /**
137
     * 当前调度信息
138
     * @var Dispatch
139
     */
140
    protected $dispatch;
141
142
    /**
143
     * 当前应用名
144
     * @var string
145
     */
146
    protected $app;
147
148
    /**
149
     * 当前控制器名
150
     * @var string
151
     */
152
    protected $controller;
153
154
    /**
155
     * 当前操作名
156
     * @var string
157
     */
158
    protected $action;
159
160
    /**
161
     * 当前语言集
162
     * @var string
163
     */
164
    protected $langset;
165
166
    /**
167
     * 当前请求参数
168
     * @var array
169
     */
170
    protected $param = [];
171
172
    /**
173
     * 当前GET参数
174
     * @var array
175
     */
176
    protected $get = [];
177
178
    /**
179
     * 当前POST参数
180
     * @var array
181
     */
182
    protected $post = [];
183
184
    /**
185
     * 当前REQUEST参数
186
     * @var array
187
     */
188
    protected $request = [];
189
190
    /**
191
     * 当前ROUTE参数
192
     * @var array
193
     */
194
    protected $route = [];
195
196
    /**
197
     * 中间件传递的参数
198
     * @var array
199
     */
200
    protected $middleware = [];
201
202
    /**
203
     * 当前PUT参数
204
     * @var array
205
     */
206
    protected $put;
207
208
    /**
209
     * 当前SESSION参数
210
     * @var array
211
     */
212
    protected $session = [];
213
214
    /**
215
     * 当前FILE参数
216
     * @var array
217
     */
218
    protected $file = [];
219
220
    /**
221
     * 当前COOKIE参数
222
     * @var array
223
     */
224
    protected $cookie = [];
225
226
    /**
227
     * 当前SERVER参数
228
     * @var array
229
     */
230
    protected $server = [];
231
232
    /**
233
     * 当前ENV参数
234
     * @var array
235
     */
236
    protected $env = [];
237
238
    /**
239
     * 当前HEADER参数
240
     * @var array
241
     */
242
    protected $header = [];
243
244
    /**
245
     * 资源类型定义
246
     * @var array
247
     */
248
    protected $mimeType = [
249
        'xml'   => 'application/xml,text/xml,application/x-xml',
250
        'json'  => 'application/json,text/x-json,application/jsonrequest,text/json',
251
        'js'    => 'text/javascript,application/javascript,application/x-javascript',
252
        'css'   => 'text/css',
253
        'rss'   => 'application/rss+xml',
254
        'yaml'  => 'application/x-yaml,text/yaml',
255
        'atom'  => 'application/atom+xml',
256
        'pdf'   => 'application/pdf',
257
        'text'  => 'text/plain',
258
        'image' => 'image/png,image/jpg,image/jpeg,image/pjpeg,image/gif,image/webp,image/*',
259
        'csv'   => 'text/csv',
260
        'html'  => 'text/html,application/xhtml+xml,*/*',
261
    ];
262
263
    /**
264
     * 当前请求内容
265
     * @var string
266
     */
267
    protected $content;
268
269
    /**
270
     * 全局过滤规则
271
     * @var array
272
     */
273
    protected $filter;
274
275
    /**
276
     * php://input内容
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
277
     * @var string
278
     */
279
    // php://input
280
    protected $input;
281
282
    /**
283
     * 请求缓存
284
     * @var array
285
     */
286
    protected $cache;
287
288
    /**
289
     * 缓存是否检查
290
     * @var bool
291
     */
292
    protected $isCheckCache;
293
294
    /**
295
     * 请求安全Key
296
     * @var string
297
     */
298
    protected $secureKey;
299
300
    /**
301
     * 是否合并Param
302
     * @var bool
303
     */
304
    protected $mergeParam = false;
305
306
    /**
307
     * 架构函数
308
     * @access public
309
     * @param  array  $options 参数
310
     */
311
    public function __construct(array $options = [])
312
    {
313
        $this->init($options);
314
315
        // 保存 php://input
316
        $this->input = file_get_contents('php://input');
317
    }
318
319
    public function init(array $options = []): void
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
320
    {
321
        $this->config = array_merge($this->config, $options);
322
323
        if (is_null($this->filter) && !empty($this->config['default_filter'])) {
0 ignored issues
show
introduced by
The condition is_null($this->filter) is always false.
Loading history...
324
            $this->filter = $this->config['default_filter'];
325
        }
326
    }
327
328
    public function config($name = null)
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
329
    {
330
        if (is_null($name)) {
331
            return $this->config;
332
        }
333
334
        return $this->config[$name] ?? null;
335
    }
336
337
    public static function __make(App $app, Config $config)
1 ignored issue
show
Coding Style introduced by
Method name "Request::__make" is invalid; only PHP magic methods should be prefixed with a double underscore
Loading history...
Coding Style introduced by
Missing function doc comment
Loading history...
338
    {
339
        $request = new static($config->get('route', []));
340
341
        $request->cookie = $app['cookie']->get();
342
        $request->server = $_SERVER;
343
        $request->env    = $app['env']->get();
344
345
        return $request;
346
    }
347
348
    /**
349
     * 创建一个URL请求
350
     * @access public
351
     * @param  string    $uri URL地址
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter name; 1 found
Loading history...
352
     * @param  string    $method 请求类型
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
353
     * @param  array     $params 请求参数
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
354
     * @param  array     $cookie
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
355
     * @param  array     $files
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
356
     * @param  array     $server
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
357
     * @param  string    $content
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
358
     * @return \think\Request
359
     */
360
    public function create(string $uri, string $method = 'GET', array $params = [], array $cookie = [], array $files = [], array $server = [], string $content = null)
361
    {
362
        $server['PATH_INFO']      = '';
363
        $server['REQUEST_METHOD'] = strtoupper($method);
364
        $info                     = parse_url($uri);
365
366
        if (isset($info['host'])) {
367
            $server['SERVER_NAME'] = $info['host'];
368
            $server['HTTP_HOST']   = $info['host'];
369
        }
370
371
        if (isset($info['scheme'])) {
372
            if ('https' === $info['scheme']) {
373
                $server['HTTPS']       = 'on';
374
                $server['SERVER_PORT'] = 443;
375
            } else {
376
                unset($server['HTTPS']);
377
                $server['SERVER_PORT'] = 80;
378
            }
379
        }
380
381
        if (isset($info['port'])) {
382
            $server['SERVER_PORT'] = $info['port'];
383
            $server['HTTP_HOST']   = $server['HTTP_HOST'] . ':' . $info['port'];
384
        }
385
386
        if (isset($info['user'])) {
387
            $server['PHP_AUTH_USER'] = $info['user'];
388
        }
389
390
        if (isset($info['pass'])) {
391
            $server['PHP_AUTH_PW'] = $info['pass'];
392
        }
393
394
        if (!isset($info['path'])) {
395
            $info['path'] = '/';
396
        }
397
398
        $options     = [];
399
        $queryString = '';
400
401
        $options[strtolower($method)] = $params;
402
403
        if (isset($info['query'])) {
404
            parse_str(html_entity_decode($info['query']), $query);
405
            if (!empty($params)) {
406
                $params      = array_replace($query, $params);
407
                $queryString = http_build_query($params, '', '&');
408
            } else {
409
                $params      = $query;
410
                $queryString = $info['query'];
411
            }
412
        } elseif (!empty($params)) {
413
            $queryString = http_build_query($params, '', '&');
414
        }
415
416
        if ($queryString) {
417
            parse_str($queryString, $get);
418
            $options['get'] = isset($options['get']) ? array_merge($get, $options['get']) : $get;
419
        }
420
421
        $server['REQUEST_URI']  = $info['path'] . ('' !== $queryString ? '?' . $queryString : '');
422
        $server['QUERY_STRING'] = $queryString;
423
        $options['cookie']      = $cookie;
424
        $options['param']       = $params;
425
        $options['file']        = $files;
426
        $options['server']      = $server;
427
        $options['url']         = $server['REQUEST_URI'];
428
        $options['baseUrl']     = $info['path'];
429
        $options['pathinfo']    = '/' == $info['path'] ? '/' : ltrim($info['path'], '/');
430
        $options['method']      = $server['REQUEST_METHOD'];
431
        $options['domain']      = isset($info['scheme']) ? $info['scheme'] . '://' . $server['HTTP_HOST'] : '';
432
        $options['content']     = $content;
433
434
        foreach ($options as $name => $item) {
435
            if (property_exists($this, $name)) {
436
                $this->$name = $item;
437
            }
438
        }
439
440
        return $this;
441
    }
442
443
    /**
444
     * 设置当前包含协议的域名
445
     * @access public
446
     * @param  string $domain 域名
447
     * @return $this
448
     */
449
    public function setDomain(string $domain)
450
    {
451
        $this->domain = $domain;
452
        return $this;
453
    }
454
455
    /**
456
     * 获取当前包含协议的域名
457
     * @access public
458
     * @param  bool $port 是否需要去除端口号
459
     * @return string
460
     */
461
    public function domain(bool $port = false): string
462
    {
463
        return $this->scheme() . '://' . $this->host($port);
464
    }
465
466
    /**
467
     * 获取当前根域名
468
     * @access public
469
     * @return string
470
     */
471
    public function rootDomain(): string
472
    {
473
        $root = $this->config['url_domain_root'];
474
475
        if (!$root) {
476
            $item  = explode('.', $this->host());
477
            $count = count($item);
478
            $root  = $count > 1 ? $item[$count - 2] . '.' . $item[$count - 1] : $item[0];
479
        }
480
481
        return $root;
482
    }
483
484
    /**
485
     * 获取当前子域名
486
     * @access public
487
     * @return string
488
     */
489
    public function subDomain(): string
490
    {
491
        if (is_null($this->subDomain)) {
0 ignored issues
show
introduced by
The condition is_null($this->subDomain) is always false.
Loading history...
492
            // 获取当前主域名
493
            $rootDomain = $this->config['url_domain_root'];
494
495
            if ($rootDomain) {
496
                // 配置域名根 例如 thinkphp.cn 163.com.cn 如果是国家级域名 com.cn net.cn 之类的域名需要配置
497
                $domain = explode('.', rtrim(stristr($this->host(), $rootDomain, true), '.'));
498
            } else {
499
                $domain = explode('.', $this->host(), -2);
500
            }
501
502
            $this->subDomain = implode('.', $domain);
503
        }
504
505
        return $this->subDomain;
506
    }
507
508
    /**
509
     * 设置当前泛域名的值
510
     * @access public
511
     * @param  string $domain 域名
512
     * @return $this
513
     */
514
    public function setPanDomain(string $domain)
515
    {
516
        $this->panDomain = $domain;
517
        return $this;
518
    }
519
520
    /**
521
     * 获取当前泛域名的值
522
     * @access public
523
     * @return string
524
     */
525
    public function panDomain(): string
526
    {
527
        return $this->panDomain ?: '';
528
    }
529
530
    /**
531
     * 设置当前完整URL 包括QUERY_STRING
532
     * @access public
533
     * @param  string $url URL地址
534
     * @return $this
535
     */
536
    public function setUrl(string $url)
537
    {
538
        $this->url = $url;
539
        return $this;
540
    }
541
542
    /**
543
     * 获取当前完整URL 包括QUERY_STRING
544
     * @access public
545
     * @param  bool $complete 是否包含完整域名
546
     * @return string
547
     */
548
    public function url(bool $complete = false): string
549
    {
550
551
        if ($this->url) {
552
            $url = $this->url;
553
        } elseif ($this->server('HTTP_X_REWRITE_URL')) {
554
            $url = $this->server('HTTP_X_REWRITE_URL');
555
        } elseif ($this->server('REQUEST_URI')) {
556
            $url = $this->server('REQUEST_URI');
557
        } elseif ($this->server('ORIG_PATH_INFO')) {
558
            $url = $this->server('ORIG_PATH_INFO') . (!empty($this->server('QUERY_STRING')) ? '?' . $this->server('QUERY_STRING') : '');
559
        } elseif (isset($_SERVER['argv'][1])) {
560
            $url = $_SERVER['argv'][1];
561
        } else {
562
            $url = '';
563
        }
564
565
        return $complete ? $this->domain() . $url : $url;
566
    }
567
568
    /**
569
     * 设置当前URL 不含QUERY_STRING
570
     * @access public
571
     * @param  string $url URL地址
572
     * @return $this
573
     */
574
    public function setBaseUrl(string $url)
575
    {
576
        $this->baseUrl = $url;
577
        return $this;
578
    }
579
580
    /**
581
     * 获取当前URL 不含QUERY_STRING
582
     * @access public
583
     * @param  bool $complete 是否包含完整域名
584
     * @return string
585
     */
586
    public function baseUrl(bool $complete = false): string
587
    {
588
        if (!$this->baseUrl) {
589
            $str           = $this->url();
590
            $this->baseUrl = strpos($str, '?') ? strstr($str, '?', true) : $str;
591
        }
592
593
        return $complete ? $this->domain() . $this->baseUrl : $this->baseUrl;
594
    }
595
596
    /**
597
     * 获取当前执行的文件 SCRIPT_NAME
598
     * @access public
599
     * @param  bool $complete 是否包含完整域名
600
     * @return string
601
     */
602
    public function baseFile(bool $complete = false): string
603
    {
604
        if (!$this->baseFile) {
605
            $url = '';
606
            if (!$this->isCli()) {
607
                $script_name = basename($this->server('SCRIPT_FILENAME'));
608
                if (basename($this->server('SCRIPT_NAME')) === $script_name) {
609
                    $url = $this->server('SCRIPT_NAME');
610
                } elseif (basename($this->server('PHP_SELF')) === $script_name) {
611
                    $url = $this->server('PHP_SELF');
612
                } elseif (basename($this->server('ORIG_SCRIPT_NAME')) === $script_name) {
613
                    $url = $this->server('ORIG_SCRIPT_NAME');
614
                } elseif (($pos = strpos($this->server('PHP_SELF'), '/' . $script_name)) !== false) {
615
                    $url = substr($this->server('SCRIPT_NAME'), 0, $pos) . '/' . $script_name;
616
                } elseif ($this->server('DOCUMENT_ROOT') && strpos($this->server('SCRIPT_FILENAME'), $this->server('DOCUMENT_ROOT')) === 0) {
617
                    $url = str_replace('\\', '/', str_replace($this->server('DOCUMENT_ROOT'), '', $this->server('SCRIPT_FILENAME')));
618
                }
619
            }
620
            $this->baseFile = $url;
621
        }
622
623
        return $complete ? $this->domain() . $this->baseFile : $this->baseFile;
624
    }
625
626
    /**
627
     * 设置URL访问根地址
628
     * @access public
629
     * @param  string $url URL地址
630
     * @return $this
631
     */
632
    public function setRoot(string $url)
633
    {
634
        $this->root = $url;
635
        return $this;
636
    }
637
638
    /**
639
     * 获取URL访问根地址
640
     * @access public
641
     * @param  bool $complete 是否包含完整域名
642
     * @return string
643
     */
644
    public function root(bool $complete = false): string
645
    {
646
        if (!$this->root) {
647
            $file = $this->baseFile();
648
            if ($file && 0 !== strpos($this->url(), $file)) {
649
                $file = str_replace('\\', '/', dirname($file));
650
            }
651
            $this->root = rtrim($file, '/');
652
        }
653
654
        return $complete ? $this->domain() . $this->root : $this->root;
655
    }
656
657
    /**
658
     * 获取URL访问根目录
659
     * @access public
660
     * @return string
661
     */
662
    public function rootUrl(): string
663
    {
664
        $base = $this->root();
665
        $root = strpos($base, '.') ? ltrim(dirname($base), DIRECTORY_SEPARATOR) : $base;
666
667
        if ('' != $root) {
668
            $root = '/' . ltrim($root, '/');
669
        }
670
671
        return $root;
672
    }
673
674
    /**
675
     * 设置当前请求的pathinfo
676
     * @access public
677
     * @param  string $pathinfo
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
678
     * @return $this
679
     */
680
    public function setPathinfo(string $pathinfo)
681
    {
682
        $this->pathinfo = $pathinfo;
683
        return $this;
684
    }
685
686
    /**
687
     * 获取当前请求URL的pathinfo信息(含URL后缀)
688
     * @access public
689
     * @return string
690
     */
691
    public function pathinfo(): string
692
    {
693
        if ($this->pathinfo) {
694
            return $this->pathinfo;
695
        }
696
697
        if (isset($_GET[$this->config['var_pathinfo']])) {
698
            // 判断URL里面是否有兼容模式参数
699
            $pathinfo = $_GET[$this->config['var_pathinfo']];
700
            unset($_GET[$this->config['var_pathinfo']]);
701
        } elseif ($this->server('PATH_INFO')) {
702
            $pathinfo = $this->server('PATH_INFO');
703
        } elseif ($this->server('REQUEST_URI')) {
704
            $pathinfo = strpos($this->server('REQUEST_URI'), '?') ? strstr($this->server('REQUEST_URI'), '?', true) : $this->server('REQUEST_URI');
705
        } elseif (isset($_SERVER['argv'][1])) {
706
            // CLI模式下 index.php controller/action/params/...
707
            $pathinfo = $_SERVER['argv'][1];
708
        }
709
710
        // 分析PATHINFO信息
711
        if (!isset($pathinfo)) {
712
            foreach ($this->config['pathinfo_fetch'] as $type) {
713
                if ($this->server($type)) {
714
                    $pathinfo = (0 === strpos($this->server($type), $this->server('SCRIPT_NAME'))) ?
0 ignored issues
show
Bug introduced by
It seems like $this->server($type) can also be of type array; however, parameter $haystack of strpos() does only seem to accept string, 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

714
                    $pathinfo = (0 === strpos(/** @scrutinizer ignore-type */ $this->server($type), $this->server('SCRIPT_NAME'))) ?
Loading history...
715
                    substr($this->server($type), strlen($this->server('SCRIPT_NAME'))) : $this->server($type);
0 ignored issues
show
Bug introduced by
It seems like $this->server($type) can also be of type array; however, parameter $string of substr() does only seem to accept string, 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

715
                    substr(/** @scrutinizer ignore-type */ $this->server($type), strlen($this->server('SCRIPT_NAME'))) : $this->server($type);
Loading history...
716
                    break;
717
                }
718
            }
719
        }
720
721
        return empty($pathinfo) || '/' == $pathinfo ? '' : ltrim($pathinfo, '/');
722
    }
723
724
    /**
725
     * 获取当前请求URL的pathinfo信息(不含URL后缀)
726
     * @access public
727
     * @return string
728
     */
729
    public function path(): string
730
    {
731
        if ($this->path) {
732
            return $this->path;
733
        }
734
735
        $suffix   = $this->config['url_html_suffix'];
736
        $pathinfo = $this->pathinfo();
737
738
        if (false === $suffix) {
739
            // 禁止伪静态访问
740
            $path = $pathinfo;
741
        } elseif ($suffix) {
742
            // 去除正常的URL后缀
743
            $path = preg_replace('/\.(' . ltrim($suffix, '.') . ')$/i', '', $pathinfo);
744
        } else {
745
            // 允许任何后缀访问
746
            $path = preg_replace('/\.' . $this->ext() . '$/i', '', $pathinfo);
747
        }
748
749
        return $path;
750
    }
751
752
    /**
753
     * 当前URL的访问后缀
754
     * @access public
755
     * @return string
756
     */
757
    public function ext(): string
758
    {
759
        return pathinfo($this->pathinfo(), PATHINFO_EXTENSION);
760
    }
761
762
    /**
763
     * 获取当前请求的时间
764
     * @access public
765
     * @param  bool $float 是否使用浮点类型
766
     * @return integer|float
767
     */
768
    public function time(bool $float = false)
769
    {
770
        return $float ? $this->server('REQUEST_TIME_FLOAT') : $this->server('REQUEST_TIME');
771
    }
772
773
    /**
774
     * 当前请求的资源类型
775
     * @access public
776
     * @return false|string
777
     */
778
    public function type()
779
    {
780
        $accept = $this->server('HTTP_ACCEPT');
781
782
        if (empty($accept)) {
783
            return false;
784
        }
785
786
        foreach ($this->mimeType as $key => $val) {
787
            $array = explode(',', $val);
788
            foreach ($array as $k => $v) {
789
                if (stristr($accept, $v)) {
790
                    return $key;
791
                }
792
            }
793
        }
794
795
        return false;
796
    }
797
798
    /**
799
     * 设置资源类型
800
     * @access public
801
     * @param  string|array  $type 资源类型名
802
     * @param  string        $val 资源类型
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
803
     * @return void
804
     */
805
    public function mimeType($type, $val = ''): void
806
    {
807
        if (is_array($type)) {
808
            $this->mimeType = array_merge($this->mimeType, $type);
809
        } else {
810
            $this->mimeType[$type] = $val;
811
        }
812
    }
813
814
    /**
815
     * 当前的请求类型
816
     * @access public
817
     * @param  bool $origin  是否获取原始请求类型
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
818
     * @return string
819
     */
820
    public function method(bool $origin = false): string
821
    {
822
        if ($origin) {
823
            // 获取原始请求类型
824
            return $this->server('REQUEST_METHOD') ?: 'GET';
825
        } elseif (!$this->method) {
826
            if (isset($_POST[$this->config['var_method']])) {
827
                $method = strtolower($_POST[$this->config['var_method']]);
828
                if (in_array($method, ['get', 'post', 'put', 'patch', 'delete'])) {
829
                    $this->method    = strtoupper($method);
830
                    $this->{$method} = $_POST;
831
                } else {
832
                    $this->method = 'POST';
833
                }
834
                unset($_POST[$this->config['var_method']]);
835
            } elseif ($this->server('HTTP_X_HTTP_METHOD_OVERRIDE')) {
836
                $this->method = strtoupper($this->server('HTTP_X_HTTP_METHOD_OVERRIDE'));
837
            } else {
838
                $this->method = $this->server('REQUEST_METHOD') ?: 'GET';
839
            }
840
        }
841
842
        return $this->method;
843
    }
844
845
    /**
846
     * 是否为GET请求
847
     * @access public
848
     * @return bool
849
     */
850
    public function isGet(): bool
851
    {
852
        return $this->method() == 'GET';
853
    }
854
855
    /**
856
     * 是否为POST请求
857
     * @access public
858
     * @return bool
859
     */
860
    public function isPost(): bool
861
    {
862
        return $this->method() == 'POST';
863
    }
864
865
    /**
866
     * 是否为PUT请求
867
     * @access public
868
     * @return bool
869
     */
870
    public function isPut(): bool
871
    {
872
        return $this->method() == 'PUT';
873
    }
874
875
    /**
876
     * 是否为DELTE请求
877
     * @access public
878
     * @return bool
879
     */
880
    public function isDelete(): bool
881
    {
882
        return $this->method() == 'DELETE';
883
    }
884
885
    /**
886
     * 是否为HEAD请求
887
     * @access public
888
     * @return bool
889
     */
890
    public function isHead(): bool
891
    {
892
        return $this->method() == 'HEAD';
893
    }
894
895
    /**
896
     * 是否为PATCH请求
897
     * @access public
898
     * @return bool
899
     */
900
    public function isPatch(): bool
901
    {
902
        return $this->method() == 'PATCH';
903
    }
904
905
    /**
906
     * 是否为OPTIONS请求
907
     * @access public
908
     * @return bool
909
     */
910
    public function isOptions(): bool
911
    {
912
        return $this->method() == 'OPTIONS';
913
    }
914
915
    /**
916
     * 是否为cli
917
     * @access public
918
     * @return bool
919
     */
920
    public function isCli(): bool
921
    {
922
        return PHP_SAPI == 'cli';
923
    }
924
925
    /**
926
     * 是否为cgi
927
     * @access public
928
     * @return bool
929
     */
930
    public function isCgi(): bool
931
    {
932
        return strpos(PHP_SAPI, 'cgi') === 0;
933
    }
934
935
    /**
936
     * 获取当前请求的参数
937
     * @access public
938
     * @param  string|array  $name 变量名
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
939
     * @param  mixed         $default 默认值
940
     * @param  string|array  $filter 过滤方法
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
941
     * @return mixed
942
     */
943
    public function param($name = '', $default = null, $filter = '')
944
    {
945
        if (empty($this->mergeParam)) {
946
            $method = $this->method(true);
947
948
            // 自动获取请求变量
949
            switch ($method) {
950
                case 'POST':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
951
                    $vars = $this->post(false);
952
                    break;
953
                case 'PUT':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
954
                case 'DELETE':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
955
                case 'PATCH':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
956
                    $vars = $this->put(false);
957
                    break;
958
                default:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
959
                    $vars = [];
960
            }
961
962
            // 当前请求参数和URL地址中的参数合并
963
            $this->param = array_merge($this->param, $this->get(false), $vars, $this->route(false));
964
965
            $this->mergeParam = true;
966
        }
967
968
        if (is_array($name)) {
969
            return $this->only($name, $this->param, $filter);
970
        }
971
972
        return $this->input($this->param, $name, $default, $filter);
973
    }
974
975
    /**
976
     * 设置路由变量
977
     * @access public
978
     * @param  array         $route 路由变量
979
     * @return $this
980
     */
981
    public function setRoute(array $route)
982
    {
983
        $this->route = array_merge($this->route, $route);
984
        return $this;
985
    }
986
987
    /**
988
     * 获取路由参数
989
     * @access public
990
     * @param  mixed         $name 变量名
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
991
     * @param  mixed         $default 默认值
992
     * @param  string|array  $filter 过滤方法
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
993
     * @return mixed
994
     */
995
    public function route($name = '', $default = null, $filter = '')
996
    {
997
        if (is_array($name)) {
998
            return $this->only($name, $this->route, $filter);
999
        }
1000
1001
        return $this->input($this->route, $name, $default, $filter);
1002
    }
1003
1004
    /**
1005
     * 获取GET参数
1006
     * @access public
1007
     * @param  mixed         $name 变量名
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1008
     * @param  mixed         $default 默认值
1009
     * @param  string|array  $filter 过滤方法
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
1010
     * @return mixed
1011
     */
1012
    public function get($name = '', $default = null, $filter = '')
1013
    {
1014
        if (empty($this->get)) {
1015
            $this->get = $_GET;
1016
        }
1017
1018
        if (is_array($name)) {
1019
            return $this->only($name, $this->get, $filter);
1020
        }
1021
1022
        return $this->input($this->get, $name, $default, $filter);
1023
    }
1024
1025
    /**
1026
     * 获取中间件传递的参数
1027
     * @access public
1028
     * @param  mixed         $name 变量名
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1029
     * @param  mixed         $default 默认值
1030
     * @return mixed
1031
     */
1032
    public function middleware($name, $default = null)
1033
    {
1034
        return $this->middleware[$name] ?? $default;
1035
    }
1036
1037
    /**
1038
     * 获取POST参数
1039
     * @access public
1040
     * @param  mixed         $name 变量名
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1041
     * @param  mixed         $default 默认值
1042
     * @param  string|array  $filter 过滤方法
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
1043
     * @return mixed
1044
     */
1045
    public function post($name = '', $default = null, $filter = '')
1046
    {
1047
        if (empty($this->post)) {
1048
            $this->post = !empty($_POST) ? $_POST : $this->getInputData($this->input);
1049
        }
1050
1051
        if (is_array($name)) {
1052
            return $this->only($name, $this->post, $filter);
1053
        }
1054
1055
        return $this->input($this->post, $name, $default, $filter);
1056
    }
1057
1058
    /**
1059
     * 获取PUT参数
1060
     * @access public
1061
     * @param  mixed             $name 变量名
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1062
     * @param  mixed             $default 默认值
1063
     * @param  string|array      $filter 过滤方法
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
1064
     * @return mixed
1065
     */
1066
    public function put($name = '', $default = null, $filter = '')
1067
    {
1068
        if (is_null($this->put)) {
0 ignored issues
show
introduced by
The condition is_null($this->put) is always false.
Loading history...
1069
            $this->put = $this->getInputData($this->input);
1070
        }
1071
1072
        if (is_array($name)) {
1073
            return $this->only($name, $this->put, $filter);
1074
        }
1075
1076
        return $this->input($this->put, $name, $default, $filter);
1077
    }
1078
1079
    protected function getInputData($content)
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
1080
    {
1081
        if (false !== strpos($this->contentType(), 'application/json') || 0 === strpos($content, '{"')) {
1082
            return (array) json_decode($content, true);
1083
        } elseif (strpos($content, '=')) {
1084
            parse_str($content, $data);
1085
            return $data;
1086
        }
1087
1088
        return [];
1089
    }
1090
1091
    /**
1092
     * 设置获取DELETE参数
1093
     * @access public
1094
     * @param  mixed             $name 变量名
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1095
     * @param  mixed             $default 默认值
1096
     * @param  string|array      $filter 过滤方法
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
1097
     * @return mixed
1098
     */
1099
    public function delete($name = '', $default = null, $filter = '')
1100
    {
1101
        return $this->put($name, $default, $filter);
1102
    }
1103
1104
    /**
1105
     * 设置获取PATCH参数
1106
     * @access public
1107
     * @param  mixed             $name 变量名
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1108
     * @param  mixed             $default 默认值
1109
     * @param  string|array      $filter 过滤方法
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
1110
     * @return mixed
1111
     */
1112
    public function patch($name = '', $default = null, $filter = '')
1113
    {
1114
        return $this->put($name, $default, $filter);
1115
    }
1116
1117
    /**
1118
     * 获取request变量
1119
     * @access public
1120
     * @param  mixed         $name 数据名称
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1121
     * @param  mixed         $default 默认值
1122
     * @param  string|array  $filter 过滤方法
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
1123
     * @return mixed
1124
     */
1125
    public function request($name = '', $default = null, $filter = '')
1126
    {
1127
        if (empty($this->request)) {
1128
            $this->request = $_REQUEST;
1129
        }
1130
1131
        if (is_array($name)) {
1132
            return $this->only($name, $this->request, $filter);
1133
        }
1134
1135
        return $this->input($this->request, $name, $default, $filter);
1136
    }
1137
1138
    /**
1139
     * 获取session数据
1140
     * @access public
1141
     * @param  string        $name 数据名称
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1142
     * @param  string        $default 默认值
1143
     * @return mixed
1144
     */
1145
    public function session(string $name = '', $default = null)
1146
    {
1147
        if (empty($this->session)) {
1148
            $this->session = Session::get();
1149
        }
1150
1151
        if ('' === $name) {
1152
            return $this->session;
1153
        }
1154
1155
        $data = $this->getData($this->session, $name);
1156
1157
        return is_null($data) ? $default : $data;
1158
    }
1159
1160
    /**
1161
     * 获取cookie参数
1162
     * @access public
1163
     * @param  mixed         $name 数据名称
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1164
     * @param  string        $default 默认值
1165
     * @param  string|array  $filter 过滤方法
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
1166
     * @return mixed
1167
     */
1168
    public function cookie(string $name = '', $default = null, $filter = '')
1169
    {
1170
        if (empty($this->cookie)) {
1171
            $this->cookie = Cookie::get();
1172
        }
1173
1174
        if (!empty($name)) {
1175
            $data = Cookie::has($name) ? Cookie::get($name) : $default;
1176
        } else {
1177
            $data = $this->cookie;
1178
        }
1179
1180
        // 解析过滤器
1181
        $filter = $this->getFilter($filter, $default);
1182
1183
        if (is_array($data)) {
1184
            array_walk_recursive($data, [$this, 'filterValue'], $filter);
1185
            reset($data);
1186
        } else {
1187
            $this->filterValue($data, $name, $filter);
1188
        }
1189
1190
        return $data;
1191
    }
1192
1193
    /**
1194
     * 获取server参数
1195
     * @access public
1196
     * @param  string        $name 数据名称
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1197
     * @param  string        $default 默认值
1198
     * @return mixed
1199
     */
1200
    public function server(string $name = '', string $default = null)
1201
    {
1202
        if (empty($name)) {
1203
            return $this->server;
1204
        } else {
1205
            $name = strtoupper($name);
1206
        }
1207
1208
        return $this->server[$name] ?? $default;
1209
    }
1210
1211
    /**
1212
     * 获取环境变量
1213
     * @access public
1214
     * @param  string        $name 数据名称
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1215
     * @param  string        $default 默认值
1216
     * @return mixed
1217
     */
1218
    public function env(string $name = '', string $default = null)
1219
    {
1220
        if (empty($name)) {
1221
            return $this->env;
1222
        } else {
1223
            $name = strtoupper($name);
1224
        }
1225
1226
        return $this->env[$name] ?? $default;
1227
    }
1228
1229
    /**
1230
     * 获取上传的文件信息
1231
     * @access public
1232
     * @param  string $name 名称
1233
     * @return null|array|\think\File
1234
     */
1235
    public function file(string $name = '')
1236
    {
1237
        if (empty($this->file)) {
1238
            $this->file = $_FILES ?? [];
1239
        }
1240
1241
        $files = $this->file;
1242
        if (!empty($files)) {
1243
1244
            if (strpos($name, '.')) {
1245
                list($name, $sub) = explode('.', $name);
1246
            }
1247
1248
            // 处理上传文件
1249
            $array = $this->dealUploadFile($files, $name);
1250
1251
            if ('' === $name) {
1252
                // 获取全部文件
1253
                return $array;
1254
            } elseif (isset($sub) && isset($array[$name][$sub])) {
1255
                return $array[$name][$sub];
1256
            } elseif (isset($array[$name])) {
1257
                return $array[$name];
1258
            }
1259
        }
1260
1261
        return;
1262
    }
1263
1264
    protected function dealUploadFile($files, $name)
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
1265
    {
1266
        $array = [];
1267
        foreach ($files as $key => $file) {
1268
            if (is_array($file['name'])) {
1269
                $item  = [];
1270
                $keys  = array_keys($file);
1271
                $count = count($file['name']);
1272
1273
                for ($i = 0; $i < $count; $i++) {
1274
                    if ($file['error'][$i] > 0) {
1275
                        if ($name == $key) {
1276
                            $this->throwUploadFileError($file['error'][$i]);
1277
                        } else {
1278
                            continue;
1279
                        }
1280
                    }
1281
1282
                    $temp['key'] = $key;
1283
1284
                    foreach ($keys as $_key) {
1285
                        $temp[$_key] = $file[$_key][$i];
1286
                    }
1287
1288
                    $item[] = (new File($temp['tmp_name']))->setUploadInfo($temp);
1289
                }
1290
1291
                $array[$key] = $item;
1292
            } else {
1293
                if ($file instanceof File) {
1294
                    $array[$key] = $file;
1295
                } else {
1296
                    if ($file['error'] > 0) {
1297
                        if ($key == $name) {
1298
                            $this->throwUploadFileError($file['error']);
1299
                        } else {
1300
                            continue;
1301
                        }
1302
                    }
1303
1304
                    $array[$key] = (new File($file['tmp_name']))->setUploadInfo($file);
1305
                }
1306
            }
1307
        }
1308
1309
        return $array;
1310
    }
1311
1312
    protected function throwUploadFileError($error)
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
1313
    {
1314
        static $fileUploadErrors = [
1315
            1 => 'upload File size exceeds the maximum value',
1316
            2 => 'upload File size exceeds the maximum value',
1317
            3 => 'only the portion of file is uploaded',
1318
            4 => 'no file to uploaded',
1319
            6 => 'upload temp dir not found',
1320
            7 => 'file write error',
1321
        ];
1322
1323
        $msg = $fileUploadErrors[$error];
1324
        throw new Exception($msg);
1325
    }
1326
1327
    /**
1328
     * 设置或者获取当前的Header
1329
     * @access public
1330
     * @param  string   $name header名称
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1331
     * @param  string   $default 默认值
1332
     * @return string|array
1333
     */
1334
    public function header(string $name = '', string $default = null)
1335
    {
1336
        if (empty($this->header)) {
1337
            $header = [];
1338
1339
            if (function_exists('apache_request_headers') && $result = apache_request_headers()) {
1340
                $header = $result;
1341
            } else {
1342
                $server = $this->server;
1343
                foreach ($server as $key => $val) {
1344
                    if (0 === strpos($key, 'HTTP_')) {
1345
                        $key          = str_replace('_', '-', strtolower(substr($key, 5)));
1346
                        $header[$key] = $val;
1347
                    }
1348
                }
1349
                if (isset($server['CONTENT_TYPE'])) {
1350
                    $header['content-type'] = $server['CONTENT_TYPE'];
1351
                }
1352
                if (isset($server['CONTENT_LENGTH'])) {
1353
                    $header['content-length'] = $server['CONTENT_LENGTH'];
1354
                }
1355
            }
1356
1357
            $this->header = array_change_key_case($header);
1358
        }
1359
1360
        if ('' === $name) {
1361
            return $this->header;
1362
        }
1363
1364
        $name = str_replace('_', '-', strtolower($name));
1365
1366
        return $this->header[$name] ?? $default;
1367
    }
1368
1369
    /**
1370
     * 获取变量 支持过滤和默认值
1371
     * @access public
1372
     * @param  array         $data 数据源
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1373
     * @param  string|false  $name 字段名
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
1374
     * @param  mixed         $default 默认值
1375
     * @param  string|array  $filter 过滤函数
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
1376
     * @return mixed
1377
     */
1378
    public function input(array $data = [], $name = '', $default = null, $filter = '')
1379
    {
1380
        if (false === $name) {
1381
            // 获取原始数据
1382
            return $data;
1383
        }
1384
1385
        $name = (string) $name;
1386
        if ('' != $name) {
1387
            // 解析name
1388
            if (strpos($name, '/')) {
1389
                list($name, $type) = explode('/', $name);
1390
            }
1391
1392
            $data = $this->getData($data, $name);
1393
1394
            if (is_null($data)) {
1395
                return $default;
1396
            }
1397
1398
            if (is_object($data)) {
1399
                return $data;
1400
            }
1401
        }
1402
1403
        return $this->filterData($data, $filter, $name, $default);
1404
    }
1405
1406
    protected function filterData($data, $filter, $name, $default)
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
1407
    {
1408
        // 解析过滤器
1409
        $filter = $this->getFilter($filter, $default);
1410
1411
        if (is_array($data)) {
1412
            array_walk_recursive($data, [$this, 'filterValue'], $filter);
1413
            reset($data);
1414
        } else {
1415
            $this->filterValue($data, $name, $filter);
1416
        }
1417
1418
        return $data;
1419
    }
1420
1421
    /**
1422
     * 获取数据
1423
     * @access public
1424
     * @param  array         $data 数据源
1425
     * @param  string        $name 字段名
1426
     * @return mixed
1427
     */
1428
    protected function getData(array $data, string $name)
1429
    {
1430
        foreach (explode('.', $name) as $val) {
1431
            if (isset($data[$val])) {
1432
                $data = $data[$val];
1433
            } else {
1434
                return;
1435
            }
1436
        }
1437
1438
        return $data;
1439
    }
1440
1441
    /**
1442
     * 设置或获取当前的过滤规则
1443
     * @access public
1444
     * @param  mixed $filter 过滤规则
1445
     * @return mixed
1446
     */
1447
    public function filter($filter = null)
1448
    {
1449
        if (is_null($filter)) {
1450
            return $this->filter;
1451
        }
1452
1453
        $this->filter = $filter;
1454
1455
        return $this;
1456
    }
1457
1458
    protected function getFilter($filter, $default)
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
1459
    {
1460
        if (is_null($filter)) {
1461
            $filter = [];
1462
        } else {
1463
            $filter = $filter ?: $this->filter;
1464
            if (is_string($filter) && false === strpos($filter, '/')) {
1465
                $filter = explode(',', $filter);
1466
            } else {
1467
                $filter = (array) $filter;
1468
            }
1469
        }
1470
1471
        $filter[] = $default;
1472
1473
        return $filter;
1474
    }
1475
1476
    /**
1477
     * 递归过滤给定的值
1478
     * @access public
1479
     * @param  mixed     $value 键值
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
1480
     * @param  mixed     $key 键名
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter name; 1 found
Loading history...
1481
     * @param  array     $filters 过滤方法+默认值
1482
     * @return mixed
1483
     */
1484
    private function filterValue(&$value, $key, $filters)
0 ignored issues
show
Coding Style introduced by
Private method name "Request::filterValue" must be prefixed with an underscore
Loading history...
1485
    {
1486
        $default = array_pop($filters);
1487
1488
        foreach ($filters as $filter) {
1489
            if (is_callable($filter)) {
1490
                // 调用函数或者方法过滤
1491
                $value = call_user_func($filter, $value);
1492
            } elseif (is_scalar($value)) {
1493
                if (false !== strpos($filter, '/')) {
1494
                    // 正则过滤
1495
                    if (!preg_match($filter, $value)) {
1496
                        // 匹配不成功返回默认值
1497
                        $value = $default;
1498
                        break;
1499
                    }
1500
                } elseif (!empty($filter)) {
1501
                    // filter函数不存在时, 则使用filter_var进行过滤
1502
                    // filter为非整形值时, 调用filter_id取得过滤id
1503
                    $value = filter_var($value, is_int($filter) ? $filter : filter_id($filter));
1504
                    if (false === $value) {
1505
                        $value = $default;
1506
                        break;
1507
                    }
1508
                }
1509
            }
1510
        }
1511
1512
        return $value;
1513
    }
1514
1515
    /**
1516
     * 是否存在某个请求参数
1517
     * @access public
1518
     * @param  string    $name 变量名
0 ignored issues
show
Coding Style introduced by
Expected 7 spaces after parameter name; 1 found
Loading history...
1519
     * @param  string    $type 变量类型
0 ignored issues
show
Coding Style introduced by
Expected 7 spaces after parameter name; 1 found
Loading history...
1520
     * @param  bool      $checkEmpty 是否检测空值
1521
     * @return bool
1522
     */
1523
    public function has(string $name, string $type = 'param', bool $checkEmpty = false): bool
1524
    {
1525
        $param = empty($this->$type) ? $this->$type() : $this->$type;
1526
1527
        // 按.拆分成多维数组进行判断
1528
        foreach (explode('.', $name) as $val) {
1529
            if (isset($param[$val])) {
1530
                $param = $param[$val];
1531
            } else {
1532
                return false;
1533
            }
1534
        }
1535
1536
        return ($checkEmpty && '' === $param) ? false : true;
1537
    }
1538
1539
    /**
1540
     * 获取指定的参数
1541
     * @access public
1542
     * @param  array            $name 变量名
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
1543
     * @param  mixed            $data 数据或者变量类型
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
1544
     * @param  string|array     $filter 过滤方法
1545
     * @return array
1546
     */
1547
    public function only(array $name, $data = 'param', $filter = ''): array
1548
    {
1549
        $data = is_array($data) ? $data : $this->$data();
1550
1551
        $item = [];
1552
        foreach ($name as $key => $val) {
1553
1554
            if (is_int($key)) {
1555
                $default = null;
1556
                $key     = $val;
1557
                if (!isset($data[$key])) {
1558
                    continue;
1559
                }
1560
            } else {
1561
                $default = $val;
1562
            }
1563
1564
            $item[$key] = $this->filterData($data[$key] ?? $default, $filter, $key, $default);
1565
        }
1566
1567
        return $item;
1568
    }
1569
1570
    /**
1571
     * 排除指定参数获取
1572
     * @access public
1573
     * @param  array  $name 变量名
1574
     * @param  string $type 变量类型
1575
     * @return mixed
1576
     */
1577
    public function except(array $name, string $type = 'param'): array
1578
    {
1579
        $param = $this->$type();
1580
1581
        foreach ($name as $key) {
1582
            if (isset($param[$key])) {
1583
                unset($param[$key]);
1584
            }
1585
        }
1586
1587
        return $param;
1588
    }
1589
1590
    /**
1591
     * 当前是否ssl
1592
     * @access public
1593
     * @return bool
1594
     */
1595
    public function isSsl(): bool
1596
    {
1597
        if ($this->server('HTTPS') && ('1' == $this->server('HTTPS') || 'on' == strtolower($this->server('HTTPS')))) {
1598
            return true;
1599
        } elseif ('https' == $this->server('REQUEST_SCHEME')) {
1600
            return true;
1601
        } elseif ('443' == $this->server('SERVER_PORT')) {
1602
            return true;
1603
        } elseif ('https' == $this->server('HTTP_X_FORWARDED_PROTO')) {
1604
            return true;
1605
        } elseif ($this->config['https_agent_name'] && $this->server($this->config['https_agent_name'])) {
1606
            return true;
1607
        }
1608
1609
        return false;
1610
    }
1611
1612
    /**
1613
     * 当前是否JSON请求
1614
     * @access public
1615
     * @return bool
1616
     */
1617
    public function isJson(): bool
1618
    {
1619
        $contentType = $this->contentType();
1620
1621
        return false !== strpos($contentType, 'json');
1622
    }
1623
1624
    /**
1625
     * 当前是否Ajax请求
1626
     * @access public
1627
     * @param  bool $ajax  true 获取原始ajax请求
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1628
     * @return bool
1629
     */
1630
    public function isAjax(bool $ajax = false): bool
1631
    {
1632
        $value  = $this->server('HTTP_X_REQUESTED_WITH');
1633
        $result = $value && 'xmlhttprequest' == strtolower($value) ? true : false;
1634
1635
        if (true === $ajax) {
1636
            return $result;
1637
        }
1638
1639
        return $this->param($this->config['var_ajax']) ? true : $result;
1640
    }
1641
1642
    /**
1643
     * 当前是否Pjax请求
1644
     * @access public
1645
     * @param  bool $pjax  true 获取原始pjax请求
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1646
     * @return bool
1647
     */
1648
    public function isPjax(bool $pjax = false): bool
1649
    {
1650
        $result = !is_null($this->server('HTTP_X_PJAX')) ? true : false;
1651
1652
        if (true === $pjax) {
1653
            return $result;
1654
        }
1655
1656
        return $this->param($this->config['var_pjax']) ? true : $result;
1657
    }
1658
1659
    /**
1660
     * 获取客户端IP地址
1661
     * @access public
1662
     * @return string
1663
     */
1664
    public function ip(): string
1665
    {
1666
        if (!empty($this->realIP)) {
1667
            return $this->realIP;
1668
        }
1669
1670
        $this->realIP = $this->server('REMOTE_ADDR', '');
1671
1672
        // 如果指定了前端代理服务器IP以及其会发送的IP头
1673
        // 则尝试获取前端代理服务器发送过来的真实IP
1674
        $proxyIp       = $this->config('proxy_server_ip');
1675
        $proxyIpHeader = $this->config('proxy_server_ip_header');
1676
1677
        if (count($proxyIp) > 0 && count($proxyIpHeader) > 0) {
1678
            // 从指定的HTTP头中依次尝试获取IP地址
1679
            // 直到获取到一个合法的IP地址
1680
            foreach ($proxyIpHeader as $header) {
1681
                $tempIP = $this->server($header);
1682
1683
                if (empty($tempIP)) {
1684
                    continue;
1685
                }
1686
1687
                $tempIP = trim(explode(',', $tempIP)[0]);
0 ignored issues
show
Bug introduced by
It seems like $tempIP can also be of type array; however, parameter $string of explode() does only seem to accept string, 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

1687
                $tempIP = trim(explode(',', /** @scrutinizer ignore-type */ $tempIP)[0]);
Loading history...
1688
1689
                if (!$this->isValidIP($tempIP)) {
1690
                    $tempIP = null;
1691
                } else {
1692
                    break;
1693
                }
1694
            }
1695
1696
            // tempIP不为空,说明获取到了一个IP地址
1697
            // 这时我们检查 REMOTE_ADDR 是不是指定的前端代理服务器之一
1698
            // 如果是的话说明该 IP头 是由前端代理服务器设置的
1699
            // 否则则是伪装的
1700
            if ($tempIP) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $tempIP seems to be defined by a foreach iteration on line 1680. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
1701
                $realIPBin = $this->ip2bin($this->realIP);
1702
1703
                foreach ($proxyIp as $ip) {
1704
                    $serverIPElements = explode('/', $ip);
1705
                    $serverIP         = $serverIPElements[0];
1706
                    $serverIPPrefix   = $serverIPElements[1] ?? 128;
1707
                    $serverIPBin      = $this->ip2bin($serverIP);
1708
1709
                    // IP类型不符
1710
                    if (strlen($realIPBin) !== strlen($serverIPBin)) {
1711
                        continue;
1712
                    }
1713
1714
                    if (strncmp($realIPBin, $serverIPBin, (int) $serverIPPrefix) === 0) {
1715
                        $this->realIP = $tempIP;
1716
                        break;
1717
                    }
1718
                }
1719
            }
1720
        }
1721
1722
        if (!$this->isValidIP($this->realIP)) {
1723
            $this->realIP = '0.0.0.0';
1724
        }
1725
1726
        return $this->realIP;
1727
    }
1728
1729
    /**
1730
     * 检测是否是合法的IP地址
1731
     *
1732
     * @param string $ip    IP地址
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 4 found
Loading history...
1733
     * @param string $type  IP地址类型 (ipv4, ipv6)
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
1734
     *
1735
     * @return boolean
1736
     */
1737
    public function isValidIP(string $ip, string $type = ''): bool
1738
    {
1739
        switch (strtolower($type)) {
1740
            case 'ipv4':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
1741
                $flag = FILTER_FLAG_IPV4;
1742
                break;
1743
            case 'ipv6':
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
1744
                $flag = FILTER_FLAG_IPV6;
1745
                break;
1746
            default:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
1747
                $flag = null;
1748
                break;
1749
        }
1750
1751
        return boolval(filter_var($ip, FILTER_VALIDATE_IP, $flag));
1752
    }
1753
1754
    /**
1755
     * 将IP地址转换为二进制字符串
1756
     *
1757
     * @param string $ip
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
1758
     *
1759
     * @return string
1760
     */
1761
    public function ip2bin(string $ip): string
1762
    {
1763
        if ($this->isValidIP($ip, 'ipv6')) {
1764
            $IPHex = str_split(bin2hex(inet_pton($ip)), 4);
1765
            foreach ($IPHex as $key => $value) {
1766
                $IPHex[$key] = intval($value, 16);
1767
            }
1768
            $IPBin = vsprintf('%016b%016b%016b%016b%016b%016b%016b%016b', $IPHex);
1769
        } else {
1770
            $IPHex = str_split(bin2hex(inet_pton($ip)), 2);
1771
            foreach ($IPHex as $key => $value) {
1772
                $IPHex[$key] = intval($value, 16);
1773
            }
1774
            $IPBin = vsprintf('%08b%08b%08b%08b', $IPHex);
1775
        }
1776
1777
        return $IPBin;
1778
    }
1779
1780
    /**
1781
     * 检测是否使用手机访问
1782
     * @access public
1783
     * @return bool
1784
     */
1785
    public function isMobile(): bool
1786
    {
1787
        if ($this->server('HTTP_VIA') && stristr($this->server('HTTP_VIA'), "wap")) {
1788
            return true;
1789
        } elseif ($this->server('HTTP_ACCEPT') && strpos(strtoupper($this->server('HTTP_ACCEPT')), "VND.WAP.WML")) {
1790
            return true;
1791
        } elseif ($this->server('HTTP_X_WAP_PROFILE') || $this->server('HTTP_PROFILE')) {
1792
            return true;
1793
        } elseif ($this->server('HTTP_USER_AGENT') && preg_match('/(blackberry|configuration\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i', $this->server('HTTP_USER_AGENT'))) {
1794
            return true;
1795
        }
1796
1797
        return false;
1798
    }
1799
1800
    /**
1801
     * 当前URL地址中的scheme参数
1802
     * @access public
1803
     * @return string
1804
     */
1805
    public function scheme(): string
1806
    {
1807
        return $this->isSsl() ? 'https' : 'http';
1808
    }
1809
1810
    /**
1811
     * 当前请求URL地址中的query参数
1812
     * @access public
1813
     * @return string
1814
     */
1815
    public function query(): string
1816
    {
1817
        return $this->server('QUERY_STRING', '');
1818
    }
1819
1820
    /**
1821
     * 设置当前请求的host(包含端口)
1822
     * @access public
1823
     * @param  string $host 主机名(含端口)
1824
     * @return $this
1825
     */
1826
    public function setHost(string $host)
1827
    {
1828
        $this->host = $host;
1829
1830
        return $this;
1831
    }
1832
1833
    /**
1834
     * 当前请求的host
1835
     * @access public
1836
     * @param bool $strict  true 仅仅获取HOST
1 ignored issue
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
1837
     * @return string
1838
     */
1839
    public function host(bool $strict = false): string
1840
    {
1841
        $host = strval($this->server('HTTP_X_REAL_HOST') ?: $this->server('HTTP_HOST'));
1842
1843
        return true === $strict && strpos($host, ':') ? strstr($host, ':', true) : $host;
1844
    }
1845
1846
    /**
1847
     * 当前请求URL地址中的port参数
1848
     * @access public
1849
     * @return string
1850
     */
1851
    public function port(): string
1852
    {
1853
        return $this->server('SERVER_PORT', '');
1854
    }
1855
1856
    /**
1857
     * 当前请求 SERVER_PROTOCOL
1858
     * @access public
1859
     * @return string
1860
     */
1861
    public function protocol(): string
1862
    {
1863
        return $this->server('SERVER_PROTOCOL', '');
1864
    }
1865
1866
    /**
1867
     * 当前请求 REMOTE_PORT
1868
     * @access public
1869
     * @return string
1870
     */
1871
    public function remotePort(): string
1872
    {
1873
        return $this->server('REMOTE_PORT', '');
1874
    }
1875
1876
    /**
1877
     * 当前请求 HTTP_CONTENT_TYPE
1878
     * @access public
1879
     * @return string
1880
     */
1881
    public function contentType(): string
1882
    {
1883
        $contentType = $this->server('CONTENT_TYPE');
1884
1885
        if ($contentType) {
1886
            if (strpos($contentType, ';')) {
1887
                list($type) = explode(';', $contentType);
1888
            } else {
1889
                $type = $contentType;
1890
            }
1891
            return trim($type);
1892
        }
1893
1894
        return '';
1895
    }
1896
1897
    /**
1898
     * 获取当前请求的路由信息
1899
     * @access public
1900
     * @param  array $route 路由名称
1901
     * @return array
1902
     */
1903
    public function routeInfo(array $route = []): array
1904
    {
1905
        if (!empty($route)) {
1906
            $this->routeInfo = $route;
1907
        }
1908
1909
        return $this->routeInfo;
1910
    }
1911
1912
    /**
1913
     * 设置或者获取当前请求的调度信息
1914
     * @access public
1915
     * @param  Dispatch  $dispatch 调度信息
1916
     * @return Dispatch
1917
     */
1918
    public function dispatch(Dispatch $dispatch = null)
1919
    {
1920
        if (!is_null($dispatch)) {
1921
            $this->dispatch = $dispatch;
1922
        }
1923
1924
        return $this->dispatch;
1925
    }
1926
1927
    /**
1928
     * 获取当前请求的安全Key
1929
     * @access public
1930
     * @return string
1931
     */
1932
    public function secureKey(): string
1933
    {
1934
        if (is_null($this->secureKey)) {
0 ignored issues
show
introduced by
The condition is_null($this->secureKey) is always false.
Loading history...
1935
            $this->secureKey = uniqid('', true);
1936
        }
1937
1938
        return $this->secureKey;
1939
    }
1940
1941
    /**
1942
     * 设置当前的应用名
1943
     * @access public
1944
     * @param  string $app 应用名
1945
     * @return $this
1946
     */
1947
    public function setApp(string $app)
1948
    {
1949
        $this->app = $app;
1950
        return $this;
1951
    }
1952
1953
    /**
1954
     * 设置当前的控制器名
1955
     * @access public
1956
     * @param  string $controller 控制器名
1957
     * @return $this
1958
     */
1959
    public function setController(string $controller)
1960
    {
1961
        $this->controller = $controller;
1962
        return $this;
1963
    }
1964
1965
    /**
1966
     * 设置当前的操作名
1967
     * @access public
1968
     * @param  string $action 操作名
1969
     * @return $this
1970
     */
1971
    public function setAction(string $action)
1972
    {
1973
        $this->action = $action;
1974
        return $this;
1975
    }
1976
1977
    /**
1978
     * 获取当前的应用名
1979
     * @access public
1980
     * @return string
1981
     */
1982
    public function app(): string
1983
    {
1984
        return $this->app ?: '';
1985
    }
1986
1987
    /**
1988
     * 获取当前的控制器名
1989
     * @access public
1990
     * @param  bool $convert 转换为小写
1991
     * @return string
1992
     */
1993
    public function controller(bool $convert = false): string
1994
    {
1995
        $name = $this->controller ?: '';
1996
        return $convert ? strtolower($name) : $name;
1997
    }
1998
1999
    /**
2000
     * 获取当前的操作名
2001
     * @access public
2002
     * @param  bool $convert 转换为小写
2003
     * @return string
2004
     */
2005
    public function action(bool $convert = false): string
2006
    {
2007
        $name = $this->action ?: '';
2008
        return $convert ? strtolower($name) : $name;
2009
    }
2010
2011
    /**
2012
     * 设置当前的语言
2013
     * @access public
2014
     * @param  string $lang 语言名
2015
     * @return $this
2016
     */
2017
    public function setLangset(string $lang)
2018
    {
2019
        $this->langset = $lang;
2020
        return $this;
2021
    }
2022
2023
    /**
2024
     * 获取当前的语言
2025
     * @access public
2026
     * @return string
2027
     */
2028
    public function langset(): string
2029
    {
2030
        return $this->langset ?: '';
2031
    }
2032
    /**
2033
     * 设置或者获取当前请求的content
2034
     * @access public
2035
     * @return string
2036
     */
2037
    public function getContent(): string
2038
    {
2039
        if (is_null($this->content)) {
0 ignored issues
show
introduced by
The condition is_null($this->content) is always false.
Loading history...
2040
            $this->content = $this->input;
2041
        }
2042
2043
        return $this->content;
2044
    }
2045
2046
    /**
2047
     * 获取当前请求的php://input
2048
     * @access public
2049
     * @return string
2050
     */
2051
    public function getInput(): string
2052
    {
2053
        return $this->input;
2054
    }
2055
2056
    /**
2057
     * 生成请求令牌
2058
     * @access public
2059
     * @param  string $name 令牌名称
2060
     * @param  mixed  $type 令牌生成方法
2061
     * @return string
2062
     */
2063
    public function token(string $name = '__token__', $type = 'md5'): string
2064
    {
2065
        $type  = is_callable($type) ? $type : 'md5';
2066
        $token = call_user_func($type, $this->server('REQUEST_TIME_FLOAT'));
2067
2068
        if ($this->isAjax()) {
2069
            header($name . ': ' . $token);
2070
        }
2071
2072
        Container::pull('session')->set($name, $token);
2073
2074
        return $token;
2075
    }
2076
2077
    /**
2078
     * 设置当前地址的请求缓存
2079
     * @access public
2080
     * @param  mixed  $key 缓存标识,支持变量规则 ,例如 item/:name/:id
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
2081
     * @param  int   $expire 缓存有效期
2082
     * @param  string $tag    缓存标签
2083
     * @param  array  $except 缓存排除
2084
     * @return mixed
2085
     */
2086
    public function cache($key = null, int $expire = null, string $tag = null, array $except = [])
2087
    {
2088
        $key    = $key ?: $this->config['request_cache'];
2089
        $expire = $expire ?: $this->config['request_cache_expire'];
2090
        $except = !empty($except) ? $except : $this->config['request_cache_except'];
2091
        $tag    = $tag ?: $this->config['request_cache_tag'];
2092
2093
        if (false === $key || !$this->isGet() || $this->isCheckCache) {
2094
            // 关闭当前缓存
2095
            return;
2096
        }
2097
2098
        // 标记请求缓存检查
2099
        $this->isCheckCache = true;
2100
2101
        foreach ($except as $rule) {
2102
            if (0 === stripos($this->url(), $rule)) {
2103
                return;
2104
            }
2105
        }
2106
2107
        if ($key instanceof \Closure) {
2108
            $key = call_user_func_array($key, [$this]);
2109
        } elseif (true === $key) {
2110
            // 自动缓存功能
2111
            $key = '__URL__';
2112
        } elseif (strpos($key, '|')) {
2113
            list($key, $fun) = explode('|', $key);
2114
        }
2115
2116
        // 特殊规则替换
2117
        if (false !== strpos($key, '__')) {
2118
            $key = str_replace(['__APP__', '__CONTROLLER__', '__ACTION__', '__URL__'], [$this->app, $this->controller, $this->action, md5($this->url(true))], $key);
2119
        }
2120
2121
        if (false !== strpos($key, ':')) {
2122
            $param = $this->param();
2123
            foreach ($param as $item => $val) {
2124
                if (is_string($val) && false !== strpos($key, ':' . $item)) {
2125
                    $key = str_replace(':' . $item, $val, $key);
2126
                }
2127
            }
2128
        } elseif (strpos($key, ']')) {
2129
            if ('[' . $this->ext() . ']' == $key) {
2130
                // 缓存某个后缀的请求
2131
                $key = md5($this->url());
2132
            } else {
2133
                return;
2134
            }
2135
        }
2136
2137
        if (isset($fun)) {
2138
            $key = $fun($key);
2139
        }
2140
2141
        $this->cache = [$key, $expire, $tag];
2142
        return $this->cache;
2143
    }
2144
2145
    /**
2146
     * 读取请求缓存设置
2147
     * @access public
2148
     * @return array|null
2149
     */
2150
    public function getCache()
2151
    {
2152
        return $this->cache;
2153
    }
2154
2155
    /**
2156
     * 设置在中间件传递的数据
2157
     * @access public
2158
     * @param  array $middleware 数据
2159
     * @return $this
2160
     */
2161
    public function withMiddleware(array $middleware)
2162
    {
2163
        $this->middleware = array_merge($this->middleware, $middleware);
2164
        return $this;
2165
    }
2166
2167
    /**
2168
     * 设置GET数据
2169
     * @access public
2170
     * @param  array $get 数据
2171
     * @return $this
2172
     */
2173
    public function withGet(array $get)
2174
    {
2175
        $this->get = $get;
2176
        return $this;
2177
    }
2178
2179
    /**
2180
     * 设置POST数据
2181
     * @access public
2182
     * @param  array $post 数据
2183
     * @return $this
2184
     */
2185
    public function withPost(array $post)
2186
    {
2187
        $this->post = $post;
2188
        return $this;
2189
    }
2190
2191
    /**
2192
     * 设置COOKIE数据
2193
     * @access public
2194
     * @param  array $cookie 数据
2195
     * @return $this
2196
     */
2197
    public function withCookie(array $cookie)
2198
    {
2199
        $this->cookie = $cookie;
2200
        return $this;
2201
    }
2202
2203
    /**
2204
     * 设置SERVER数据
2205
     * @access public
2206
     * @param  array $server 数据
2207
     * @return $this
2208
     */
2209
    public function withServer(array $server)
2210
    {
2211
        $this->server = array_change_key_case($server, CASE_UPPER);
2212
        return $this;
2213
    }
2214
2215
    /**
2216
     * 设置HEADER数据
2217
     * @access public
2218
     * @param  array $header 数据
2219
     * @return $this
2220
     */
2221
    public function withHeader(array $header)
2222
    {
2223
        $this->header = array_change_key_case($header);
2224
        return $this;
2225
    }
2226
2227
    /**
2228
     * 设置ENV数据
2229
     * @access public
2230
     * @param  array $env 数据
2231
     * @return $this
2232
     */
2233
    public function withEnv(array $env)
2234
    {
2235
        $this->env = $env;
2236
        return $this;
2237
    }
2238
2239
    /**
2240
     * 设置php://input数据
2241
     * @access public
2242
     * @param  string $input RAW数据
2243
     * @return $this
2244
     */
2245
    public function withInput(string $input)
2246
    {
2247
        $this->input = $input;
2248
        return $this;
2249
    }
2250
2251
    /**
2252
     * 设置文件上传数据
2253
     * @access public
2254
     * @param  array $files 上传信息
2255
     * @return $this
2256
     */
2257
    public function withFiles(array $files)
2258
    {
2259
        $this->file = $files;
2260
        return $this;
2261
    }
2262
2263
    /**
2264
     * 设置ROUTE变量
2265
     * @access public
2266
     * @param  array $route 数据
2267
     * @return $this
2268
     */
2269
    public function withRoute(array $route)
2270
    {
2271
        $this->route = $route;
2272
        return $this;
2273
    }
2274
2275
    /**
2276
     * 设置中间传递数据
2277
     * @access public
2278
     * @param  string    $name  参数名
2279
     * @param  mixed     $value 值
2280
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
2281
    public function __set(string $name, $value)
2282
    {
2283
        $this->middleware[$name] = $value;
2284
    }
2285
2286
    /**
2287
     * 获取中间传递数据的值
2288
     * @access public
2289
     * @param  string $name 名称
2290
     * @return mixed
2291
     */
2292
    public function __get(string $name)
2293
    {
2294
        return $this->middleware($name);
2295
    }
2296
2297
    /**
2298
     * 检测请求数据的值
2299
     * @access public
2300
     * @param  string $name 名称
2301
     * @return boolean
2302
     */
2303
    public function __isset(string $name): bool
2304
    {
2305
        return isset($this->param[$name]);
2306
    }
2307
}
2308