Completed
Push — master ( f6fecd...4287ac )
by zhu
01:59
created

Ip   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 16
c 2
b 0
f 0
lcom 1
cbo 0
dl 0
loc 89
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
C find() 0 49 10
A init() 0 18 4
A __destruct() 0 6 2
1
<?php namespace Zhuzhichao\IpLocationZh;
2
3
use Exception;
4
5
class Ip
6
{
7
8
    private static $ip = null;
9
10
    private static $fp = null;
11
12
    private static $offset = null;
13
14
    private static $index = null;
15
16
    private static $cached = array();
17
18
    public static function find($ip)
19
    {
20
        if (empty( $ip ) === true) {
21
            return 'N/A';
22
        }
23
24
        $nip   = gethostbyname($ip);
25
        $ipdot = explode('.', $nip);
26
27
        if ($ipdot[0] < 0 || $ipdot[0] > 255 || count($ipdot) !== 4) {
28
            return 'N/A';
29
        }
30
31
        if (isset( self::$cached[$nip] ) === true) {
32
            return self::$cached[$nip];
33
        }
34
35
        if (self::$fp === null) {
36
            self::init();
37
        }
38
39
        $nip2 = pack('N', ip2long($nip));
40
41
        $tmp_offset = (int) $ipdot[0] * 4;
42
        $start      = unpack('Vlen',
43
            self::$index[$tmp_offset].self::$index[$tmp_offset + 1].self::$index[$tmp_offset + 2].self::$index[$tmp_offset + 3]);
44
45
        $index_offset = $index_length = null;
46
        $max_comp_len = self::$offset['len'] - 1024 - 4;
47
        for ($start = $start['len'] * 8 + 1024; $start < $max_comp_len; $start += 8) {
48
            if (self::$index{$start}.self::$index{$start + 1}.self::$index{$start + 2}.self::$index{$start + 3} >= $nip2) {
49
                $index_offset = unpack('Vlen',
50
                    self::$index{$start + 4}.self::$index{$start + 5}.self::$index{$start + 6}."\x0");
51
                $index_length = unpack('Clen', self::$index{$start + 7});
52
53
                break;
54
            }
55
        }
56
57
        if ($index_offset === null) {
58
            return 'N/A';
59
        }
60
61
        fseek(self::$fp, self::$offset['len'] + $index_offset['len'] - 1024);
62
63
        self::$cached[$nip] = explode("\t", fread(self::$fp, $index_length['len']));
64
65
        return self::$cached[$nip];
66
    }
67
68
    private static function init()
69
    {
70
        if (self::$fp === null) {
71
            self::$ip = new self();
72
73
            self::$fp = fopen(__DIR__.'/17monipdb.dat', 'rb');
74
            if (self::$fp === false) {
75
                throw new Exception('Invalid 17monipdb.dat file!');
76
            }
77
78
            self::$offset = unpack('Nlen', fread(self::$fp, 4));
79
            if (self::$offset['len'] < 4) {
80
                throw new Exception('Invalid 17monipdb.dat file!');
81
            }
82
83
            self::$index = fread(self::$fp, self::$offset['len'] - 4);
84
        }
85
    }
86
87
    public function __destruct()
88
    {
89
        if (self::$fp !== null) {
90
            fclose(self::$fp);
91
        }
92
    }
93
}