IpInfo::setOutTime()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
ccs 0
cts 3
cp 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 2
1
<?php
2
3
namespace IpInfo;
4
5
6
use IpInfo\Exceptions\GetIpIpInfoFailedException;
7
use IpInfo\Exceptions\IpIllegalException;
8
use IpInfo\Exceptions\MethodNotExistException;
9
10
/**
11
 * Class IpInfo
12
 * @package IpInfo
13
 */
14
class IpInfo
15
{
16
    /**
17
     * @var
18
     */
19
    private $ip;
20
    /**
21
     * @var
22
     */
23
    private $info = [
24
        'ip'      => '',
25
        'country' => '',
26
        'area'    => '',
27
        'region'  => '',
28
        'city'    => '',
29
        'county'  => '',
30
        'isp'     => '',
31
    ];
32
    /**
33
     * 请求淘宝 IP 库 api 超时时间
34
     * @var int
35
     */
36
    private $outTime = 1;
37
38
    /**
39
     * IpInfo constructor.
40
     *
41
     * @param $ip
42
     *
43
     * @throws IpIllegalException
44
     */
45 9
    public function __construct($ip)
46
    {
47 9
        $this->ip = $ip;
48 9
        $this->query();
49 9
    }
50
51
    /**
52
     * @param string $delimiter
53
     * @param bool   $full
54
     *
55
     * @return string
56
     */
57 9
    public function address($delimiter = ' ', $full = false)
58
    {
59
        $struct = [
60 9
            $this->info['country'],
61 9
            $this->info['area'],
62 9
            $this->info['region'],
63 9
            $this->info['city'],
64 9
            $this->info['county'],
65 9
        ];
66 9
        if (!$full) {
67 9
            array_splice($struct, 1, 1);
68 9
        }
69 9
        $struct = array_filter($struct);
70
71 9
        return implode($delimiter, $struct);
72
    }
73
74
    /**
75
     * @return array ip 的信息
76
     */
77 1
    public function info()
78
    {
79 1
        return $this->info;
80
    }
81
82
    /**
83
     * @param $name
84
     * @param $arguments
85
     *
86
     * @return mixed
87
     * @throws MethodNotExistException
88
     */
89 7
    public function __call($name, $arguments)
90
    {
91
92 7
        if (isset($this->info, $name)) {
93 7
            return $this->info[$this->snakeCase($name)];
94
        } else {
95
            throw new MethodNotExistException('Call a Not Exist Method:' . $name);
96
        }
97
    }
98
99
    /**
100
     * @return mixed
101
     */
102
    public function getOutTime()
103
    {
104
        return $this->outTime;
105
    }
106
107
    /**
108
     * @param mixed $outTime
109
     *
110
     * @return $this
111
     */
112
    public function setOutTime($outTime)
113
    {
114
        $this->outTime = $outTime;
115
116
        return $this;
117
    }
118
119
    /**
120
     * @throws GetIpIpInfoFailedException
121
     */
122 9
    private function query()
123
    {
124 9
        $this->info['ip'] = $this->ip;
125 9
        if ($this->ip === '127.0.0.1') {
126
            $this->info['country'] = '本机';
127 9
        } elseif ($this->isInternal()) {
128
            $this->info['country'] = 'INNA 保留地址';
129
        } else {
130
            // 先通过 api 获取,api 获取失败的话通过本地数据库获取
131 9
            $result = $this->apiQuery();
132 9
            if ($result === false) {
133
                // api 获取失败的话进行本地获取
134
                $result = $this->localQuery();
135
            }
136
137 9
            $this->info = $result;
138
        }
139 9
    }
140
141 9
    private function apiQuery()
142
    {
143 9
        return (new IpTaobaoApiQuery)->setOutTime($this->outTime)->query($this->ip);
144
    }
145
146
    private function localQuery()
147
    {
148
        return IpLocalQuery::create()->query($this->ip);
149
    }
150
151 9
    private function isInternal()
152
    {
153 9
        $ipLong   = ip2long($this->ip);
154 9
        $netLocal = ip2long('127.255.255.255') >> 24; //127.x.x.x
155 9
        $netA     = ip2long('10.255.255.255') >> 24; //A类网预留ip的网络地址
156 9
        $netB     = ip2long('172.31.255.255') >> 20; //B类网预留ip的网络地址
157 9
        $netC     = ip2long('192.168.255.255') >> 16; //C类网预留ip的网络地址
158
159 9
        return $ipLong >> 24 === $netLocal || $ipLong >> 24 === $netA || $ipLong >> 20 === $netB || $ipLong >> 16 === $netC;
160
    }
161
162
    /**
163
     * @param        $value
164
     * @param string $delimiter
165
     *
166
     * @return mixed|string
167
     */
168 7
    private function snakeCase($value, $delimiter = '_')
169
    {
170 7
        if (!ctype_lower($value)) {
171
            $value = preg_replace('/\s+/u', '', $value);
172
            $value = strtolower(preg_replace('/(.)(?=[A-Z])/u', '$1' . $delimiter, $value));
173
        }
174
175 7
        return $value;
176
    }
177
}