GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Request::getHostInfo()   B
last analyzed

Complexity

Conditions 11
Paths 15

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 132

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 13
c 1
b 0
f 0
nc 15
nop 0
dl 0
loc 18
ccs 0
cts 18
cp 0
crap 132
rs 7.3166

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Class Request
4
 *
5
 * @link https://www.icy2003.com/
6
 * @author icy2003 <[email protected]>
7
 * @copyright Copyright (c) 2017, icy2003
8
 * @see https://github.com/yiisoft/yii2/blob/master/framework/web/Request.php
9
 */
10
namespace icy2003\php\ihelpers;
11
12
use Exception;
13
use icy2003\php\C;
14
use icy2003\php\I;
15
16
/**
17
 * 请求相关
18
 */
19
class Request
20
{
21
22
    /**
23
     * 要检查是否通过 HTTPS 建立连接的头的数组列表
24
     *
25
     * 数组键是头名称,数组值是指示安全连接的头值列表
26
     *
27
     * 头名称和值的匹配不区分大小写
28
     *
29
     * 不建议把不安全的邮件头放在这里
30
     *
31
     * @var array
32
     */
33
    private $__secureProtocolHeaders = [
34
        'x-forwarded-proto' => ['https'], // Common
35
        'front-end-https' => ['on'], // Microsoft
36
    ];
37
38
    /**
39
     * 代理存储实际客户端 IP 的头列表
40
     *
41
     * 不建议把不安全的邮件头放在这里
42
     *
43
     * 头名称的匹配不区分大小写
44
     *
45
     * @var array
46
     */
47
    private $__ipHeaders = [
48
        'x-forwarded-for', // Common
49
    ];
50
51
    /**
52
     * 头列表
53
     *
54
     * @var array
55
     */
56
    private $__headers;
57
58
    /**
59
     * 用于指示请求是 PUT、PATCH、DELETE 的 POST 参数的名称
60
     *
61
     * @var string
62
     */
63
    private $__methodParam = '_method';
64
65
    /**
66
     * 返回头列表
67
     *
68
     * @return array
69
     */
70
    public function getHeaders()
71
    {
72
        if (null === $this->__headers) {
73
            if (function_exists('getallheaders')) {
74
                $headers = getallheaders();
75
                foreach ($headers as $name => $value) {
76
                    $this->__headers[strtolower($name)][] = $value;
77
                }
78
            } elseif (function_exists('http_get_request_headers')) {
79
                $headers = http_get_request_headers();
80
                foreach ($headers as $name => $value) {
81
                    $this->__headers[strtolower($name)][] = $value;
82
                }
83
            } else {
84
                foreach ($_SERVER as $name => $value) {
85
                    if (0 === strncmp($name, 'HTTP_', 5)) {
86
                        $name = str_replace('_', '-', substr($name, 5));
87
                        $this->__headers[strtolower($name)][] = $value;
88
                    }
89
                }
90
            }
91
        }
92
        return $this->__headers;
93
    }
94
95
    /**
96
     * 获取某个头的第一个值
97
     *
98
     * @param string $name
99
     *
100
     * @return string
101
     */
102
    public function getHeader($name)
103
    {
104
        return (string)Arrays::first((array)I::get($this->getHeaders(), $name, []));
105
    }
106
107
    /**
108
     * 返回当前的请求方法,可以是:GET、POST、HEAD、PUT、PATCH、DELETE
109
     *
110
     * @return string
111
     */
112
    public function getMethod()
113
    {
114
        // 出于安全原因,不允许写方法(POST、PATCH、DELETE等)降级为读方法(GET、HEAD、OPTIONS)
115
        if (isset($_POST[$this->__methodParam]) && !in_array($method = strtoupper($_POST[$this->__methodParam]), ['GET', 'HEAD', 'OPTIONS'])) {
116
            return $method;
117
        }
118
        if ($method = (string)I::get($this->getHeaders(), 'x-http-method-override')) {
119
            return strtoupper($method);
120
        }
121
        if (isset($_SERVER['REQUEST_METHOD'])) {
122
            return strtoupper($_SERVER['REQUEST_METHOD']);
123
        }
124
        return 'GET';
125
    }
126
127
    /**
128
     * 判断是否是 GET 请求
129
     *
130
     * @return boolean
131
     */
132
    public function isGet()
133
    {
134
        return 'GET' === $this->getMethod();
135
    }
136
137
    /**
138
     * 判断是否是 OPTIONS 请求
139
     *
140
     * @return boolean
141
     */
142
    public function isOptions()
143
    {
144
        return 'OPTIONS' === $this->getMethod();
145
    }
146
147
    /**
148
     * 判断是否是 HEAD 请求
149
     *
150
     * @return boolean
151
     */
152
    public function isHead()
153
    {
154
        return 'HEAD' === $this->getMethod();
155
    }
156
157
    /**
158
     * 判断是否是 POST 请求
159
     *
160
     * @return boolean
161
     */
162
    public function isPost()
163
    {
164
        return 'POST' === $this->getMethod();
165
    }
166
167
    /**
168
     * 判断是否是 DELETE 请求
169
     *
170
     * @return boolean
171
     */
172
    public function isDelete()
173
    {
174
        return 'DELETE' === $this->getMethod();
175
    }
176
177
    /**
178
     * 判断是否是 PUT 请求
179
     *
180
     * @return boolean
181
     */
182
    public function isPut()
183
    {
184
        return 'PUT' === $this->getMethod();
185
    }
186
187
    /**
188
     * 判断是否是 PATCH 请求
189
     *
190
     * @return boolean
191
     */
192
    public function isPatch()
193
    {
194
        return 'PATCH' === $this->getMethod();
195
    }
196
197
    /**
198
     * 判断是否是 AJAX 请求
199
     *
200
     * @return boolean
201
     */
202
    public function isAjax()
203
    {
204
        return 'XMLHttpRequest' === $this->getHeader('x-requested-with');
205
    }
206
207
    /**
208
     * 是否是 pjax 请求
209
     *
210
     * @return boolean
211
     */
212
    public function isPjax()
213
    {
214
        return $this->isAjax() && '' !== $this->getHeader('x-pjax');
215
    }
216
217
    /**
218
     * 是否是 flash 请求
219
     *
220
     * @return boolean
221
     */
222
    public function isFlash()
223
    {
224
        $userAgent = $this->getUserAgent();
225
        return Strings::isContains($userAgent, 'Shockwave') || Strings::isContains($userAgent, 'Flash');
226
    }
227
228
    /**
229
     * 请求体
230
     *
231
     * @var string
232
     */
233
    private $__rawBody;
234
235
    /**
236
     * 获取请求体
237
     *
238
     * @return string
239
     */
240
    public function getRawBody()
241
    {
242
        if (null === $this->__rawBody) {
243
            $this->__rawBody = file_get_contents('php://input');
244
        }
245
        return $this->__rawBody;
246
    }
247
248
    /**
249
     * 设置请求体
250
     *
251
     * @param string $rawBody
252
     *
253
     * @return static
254
     */
255
    public function setRawBody($rawBody)
256
    {
257
        $this->__rawBody = $rawBody;
258
        return $this;
259
    }
260
261
    /**
262
     * 请求参数
263
     *
264
     * @var array
265
     */
266
    private $__bodyParams;
267
268
    /**
269
     * 返回请求体参数
270
     *
271
     * @return array
272
     */
273
    public function getBodyParams()
274
    {
275
        if (null === $this->__bodyParams) {
276
            if (isset($_POST[$this->__methodParam])) {
277
                $this->__bodyParams = $_POST;
278
                unset($this->__bodyParams[$this->__methodParam]);
279
            } else {
280
                $contentType = $this->getContentType();
281
                if (($pos = strpos($contentType, ';')) !== false) {
282
                    // application/json; charset=UTF-8
283
                    $contentType = substr($contentType, 0, $pos);
284
                }
285
                if ('application/json' == $contentType) {
286
                    $this->__bodyParams = (array)Json::decode($this->getRawBody());
287
                } elseif ('POST' === $this->getMethod()) {
288
                    $this->__bodyParams = $_POST;
289
                } else {
290
                    $this->__bodyParams = [];
291
                    mb_parse_str($this->getRawBody(), $this->__bodyParams);
292
                }
293
            }
294
        }
295
        return $this->__bodyParams;
296
    }
297
298
    /**
299
     * 设置请求体参数
300
     *
301
     * @param array $bodyParams
302
     *
303
     * @return static
304
     */
305
    public function setBodyParams($bodyParams)
306
    {
307
        $this->__bodyParams = $bodyParams;
308
        return $this;
309
    }
310
311
    /**
312
     * 返回某个请求体参数
313
     *
314
     * @param string $name 请求参数名
315
     * @param mixed $defaultValue 默认值
316
     *
317
     * @return mixed
318
     */
319
    public function getBodyParam($name, $defaultValue = null)
320
    {
321
        return I::get($this->getBodyParams(), $name, $defaultValue);
322
    }
323
324
    /**
325
     * 返回 POST 请求参数
326
     *
327
     * @param string $name POST 参数
328
     * @param mixed $defaultValue 默认值
329
     *
330
     * @return mixed
331
     */
332
    public function post($name = null, $defaultValue = null)
333
    {
334
        if (null === $name) {
335
            return $this->getBodyParams();
336
        }
337
        return $this->getBodyParam($name, $defaultValue);
338
    }
339
340
    /**
341
     * GET 参数
342
     *
343
     * @var array
344
     */
345
    private $__queryParams;
346
347
    /**
348
     * 返回 GET 参数
349
     *
350
     * @return array
351
     */
352
    public function getQueryParams()
353
    {
354
        if (null === $this->__queryParams) {
355
            return $_GET;
356
        }
357
        return $this->__queryParams;
358
    }
359
360
    /**
361
     * 设置 GET 参数
362
     *
363
     * @param array $queryParams
364
     *
365
     * @return static
366
     */
367
    public function setQueryParams($queryParams)
368
    {
369
        $this->__queryParams = $queryParams;
370
        return $this;
371
    }
372
373
    /**
374
     * 返回某个 GET 参数
375
     *
376
     * @param string $name GET 参数名
377
     * @param mixed $defaultValue 默认值
378
     *
379
     * @return mixed
380
     */
381
    public function getQueryParam($name, $defaultValue = null)
382
    {
383
        return I::get($this->getQueryParams(), $name, $defaultValue);
384
    }
385
386
    /**
387
     * 返回 GET 参数
388
     *
389
     * @param string $name GET 参数名
390
     * @param mixed $defaultValue 默认值
391
     *
392
     * @return mixed
393
     */
394
    public function get($name = null, $defaultValue = null)
395
    {
396
        if (null === $name) {
397
            return $this->getQueryParams();
398
        }
399
        return $this->getQueryParam($name, $defaultValue);
400
    }
401
402
    /**
403
     * 主机
404
     *
405
     * @var string
406
     */
407
    private $__hostInfo;
408
409
    /**
410
     * 获取主机
411
     *
412
     * @return string
413
     */
414
    public function getHostInfo()
415
    {
416
        if (null === $this->__hostInfo) {
417
            $secure = $this->isSecureConnection();
418
            $http = $secure ? 'https' : 'http';
419
            if (I::get($this->getHeaders(), 'x-forwarded-host')) {
420
                $this->__hostInfo = $http . '://' . trim((string)Arrays::first(explode(',', $this->getHeader('x-forwarded-host'))));
421
            } elseif (I::get($this->getHeaders(), 'host')) {
422
                $this->__hostInfo = $http . '://' . $this->getHeader('host');
423
            } elseif (isset($_SERVER['SERVER_NAME'])) {
424
                $this->__hostInfo = $http . '://' . $_SERVER['SERVER_NAME'];
425
                $port = $secure ? $this->getSecurePort() : $this->getPort();
426
                if ((80 !== $port && !$secure) || (443 !== $port && $secure)) {
427
                    $this->__hostInfo .= ':' . $port;
428
                }
429
            }
430
        }
431
        return $this->__hostInfo;
432
    }
433
434
    /**
435
     * 设置主机
436
     *
437
     * @param string|null $value
438
     *
439
     * @return static
440
     */
441
    public function setHostInfo($value)
442
    {
443
        $this->__hostName = $value;
444
        $this->__hostInfo = null === $value ? null : rtrim($value, '/');
445
        return $this;
446
    }
447
448
    /**
449
     * 主机名
450
     *
451
     * @var string
452
     */
453
    private $__hostName;
454
455
    /**
456
     * 获取主机名
457
     *
458
     * @return string
459
     */
460
    public function getHostName()
461
    {
462
        if (null === $this->__hostName) {
463
            $this->__hostName = parse_url($this->getHostInfo(), PHP_URL_HOST);
464
        }
465
        return $this->__hostName;
466
    }
467
468
    /**
469
     * base url
470
     *
471
     * @var string
472
     */
473
    private $__baseUrl;
474
475
    /**
476
     * 获取 base 地址
477
     *
478
     * @return string
479
     */
480
    public function getBaseUrl()
481
    {
482
        if (null === $this->__baseUrl) {
483
            $this->__baseUrl = rtrim(dirname($this->getScriptUrl()), '/\\');
484
        }
485
        return $this->__baseUrl;
486
    }
487
488
    /**
489
     * 脚本 url
490
     *
491
     * @var string
492
     */
493
    private $__scriptUrl;
494
495
    /**
496
     * 获取脚本地址
497
     *
498
     * @return string
499
     */
500
    public function getScriptUrl()
501
    {
502
        if (null === $this->__scriptUrl) {
503
            $scriptFile = $this->getScriptFile();
504
            $scriptName = basename($scriptFile);
505
            if (isset($_SERVER['SCRIPT_NAME']) && basename($_SERVER['SCRIPT_NAME']) === $scriptName) {
506
                $this->__scriptUrl = $_SERVER['SCRIPT_NAME'];
507
            } elseif (isset($_SERVER['PHP_SELF']) && basename($_SERVER['PHP_SELF']) === $scriptName) {
508
                $this->__scriptUrl = $_SERVER['PHP_SELF'];
509
            } elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $scriptName) {
510
                $this->__scriptUrl = $_SERVER['ORIG_SCRIPT_NAME'];
511
            } elseif (isset($_SERVER['PHP_SELF']) && ($pos = strpos($_SERVER['PHP_SELF'], '/' . $scriptName)) !== false) {
512
                $this->__scriptUrl = substr($_SERVER['SCRIPT_NAME'], 0, $pos) . '/' . $scriptName;
513
            } elseif (!empty($_SERVER['DOCUMENT_ROOT']) && strpos($scriptFile, $_SERVER['DOCUMENT_ROOT']) === 0) {
514
                $this->__scriptUrl = str_replace([$_SERVER['DOCUMENT_ROOT'], '\\'], ['', '/'], $scriptFile);
515
            } else {
516
                throw new Exception('无法检测出脚本地址');
517
            }
518
        }
519
        return $this->__scriptUrl;
520
    }
521
522
    /**
523
     * 设置脚本地址
524
     *
525
     * @param string|null $value
526
     *
527
     * @return static
528
     */
529
    public function setScriptUrl($value)
530
    {
531
        $this->__scriptUrl = null === $value ? null : '/' . trim($value, '/');
532
        return $this;
533
    }
534
535
    /**
536
     * 脚本文件
537
     *
538
     * @var string
539
     */
540
    private $__scriptFile;
541
542
    /**
543
     * 获取脚本文件路径
544
     *
545
     * @return string
546
     */
547
    public function getScriptFile()
548
    {
549
        if (null !== $this->__scriptFile) {
550
            return $this->__scriptFile;
551
        }
552
        if (isset($_SERVER['SCRIPT_FILENAME'])) {
553
            return $_SERVER['SCRIPT_FILENAME'];
554
        }
555
        throw new Exception('无法检测出脚本文件路径');
556
    }
557
558
    /**
559
     * 设置脚本文件路径
560
     *
561
     * @param string $value
562
     *
563
     * @return static
564
     */
565
    public function setScriptFile($value)
566
    {
567
        $this->__scriptFile = $value;
568
        return $this;
569
    }
570
571
    /**
572
     * 安全请求的端口号
573
     *
574
     * @var int
575
     */
576
    private $__securePort;
577
578
    /**
579
     * 获取安全请求的端口号
580
     *
581
     * @return int
582
     */
583
    public function getSecurePort()
584
    {
585
        if (null === $this->__securePort) {
586
            $serverPort = $this->getServerPort();
587
            $this->__securePort = $this->isSecureConnection() && null !== $serverPort ? $serverPort : 443;
588
        }
589
        return $this->__securePort;
590
    }
591
592
    /**
593
     * 端口号
594
     *
595
     * @var int
596
     */
597
    private $__port;
598
599
    /**
600
     * 获取端口号
601
     *
602
     * @return int
603
     */
604
    public function getPort()
605
    {
606
        if (null === $this->__port) {
607
            $serverPort = $this->getServerPort();
608
            $this->__port = !$this->isSecureConnection() && null !== $serverPort ? $serverPort : 80;
609
        }
610
        return $this->__port;
611
    }
612
613
    /**
614
     * 获取 GET 字符串
615
     *
616
     * @return string
617
     */
618
    public function getQueryString()
619
    {
620
        return (string)I::get($_SERVER, 'QUERY_STRING', '');
621
    }
622
623
    /**
624
     * 判断是否是 HTTPS 连接
625
     *
626
     * @return boolean
627
     */
628
    public function isSecureConnection()
629
    {
630
        if (isset($_SERVER['HTTPS']) && (strcasecmp($_SERVER['HTTPS'], 'on') === 0 || $_SERVER['HTTPS'] == 1)) {
631
            return true;
632
        }
633
        foreach ($this->__secureProtocolHeaders as $header => $values) {
634
            if ($headerValue = $this->getHeader($header)) {
635
                foreach ($values as $value) {
636
                    if (strcasecmp($headerValue, $value) === 0) {
637
                        return true;
638
                    }
639
                }
640
            }
641
        }
642
643
        return false;
644
    }
645
646
    /**
647
     * 获取服务器名
648
     *
649
     * @return string
650
     */
651
    public function getServerName()
652
    {
653
        return (string)I::get($_SERVER, 'SERVER_NAME');
654
    }
655
656
    /**
657
     * 获取服务器端口
658
     *
659
     * @return integer
660
     */
661
    public function getServerPort()
662
    {
663
        return (int)I::get($_SERVER, 'SERVER_PORT');
664
    }
665
666
    /**
667
     * 返回 URL 引用
668
     *
669
     * @return string
670
     */
671
    public function getReferrer()
672
    {
673
        return $this->getHeader('referer');
674
    }
675
676
    /**
677
     * 返回 CORS 请求的 URL 源
678
     *
679
     * @return string
680
     */
681
    public function getOrigin()
682
    {
683
        return $this->getHeader('origin');
684
    }
685
686
    /**
687
     * 返回用户代理
688
     *
689
     * @return string
690
     */
691
    public function getUserAgent()
692
    {
693
        return $this->getHeader('user-agent');
694
    }
695
696
    /**
697
     * 返回客户端 IP
698
     *
699
     * @return string
700
     */
701
    public function getUserIP()
702
    {
703
        foreach ($this->__ipHeaders as $ipHeader) {
704
            if (I::get($this->getHeaders(), $ipHeader)) {
705
                return trim(Arrays::first(explode(',', $this->getHeader($ipHeader))));
0 ignored issues
show
Bug introduced by
It seems like icy2003\php\ihelpers\Arr...>getHeader($ipHeader))) can also be of type null; however, parameter $string of trim() 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

705
                return trim(/** @scrutinizer ignore-type */ Arrays::first(explode(',', $this->getHeader($ipHeader))));
Loading history...
706
            }
707
        }
708
        return $this->getRemoteIP();
709
    }
710
711
    /**
712
     * 返回远端 IP
713
     *
714
     * @return string
715
     */
716
    public function getRemoteIP()
717
    {
718
        return (string)I::get($_SERVER, 'REMOTE_ADDR');
719
    }
720
721
    /**
722
     * 返回此连接另一端的主机名
723
     *
724
     * @return string
725
     */
726
    public function getRemoteHost()
727
    {
728
        return (string)I::get($_SERVER, 'REMOTE_HOST');
729
    }
730
731
    /**
732
     * 返回请求内容类型
733
     *
734
     * @return string
735
     */
736
    public function getContentType()
737
    {
738
        if (isset($_SERVER['CONTENT_TYPE'])) {
739
            return $_SERVER['CONTENT_TYPE'];
740
        }
741
        return $this->getHeader('content-type');
742
    }
743
744
}
745