1 | <?php |
||
15 | final class Ip extends Embeddable |
||
16 | { |
||
17 | /** @var int */ |
||
18 | private $version = 4; |
||
19 | |||
20 | /** |
||
21 | * @param string $value |
||
22 | * |
||
23 | * @throws \InvalidArgumentException |
||
24 | */ |
||
25 | 77 | public function __construct($value) |
|
26 | { |
||
27 | 77 | if (false === filter_var($value, FILTER_VALIDATE_IP)) { |
|
28 | 14 | throw new \InvalidArgumentException('Invalid IP address.'); |
|
29 | } |
||
30 | |||
31 | 63 | $this->value = (string)$value; |
|
32 | |||
33 | 63 | if (false !== filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { |
|
34 | 45 | $this->version = 6; |
|
35 | 45 | $this->value = $this->getCondensed(); |
|
36 | } |
||
37 | 63 | } |
|
38 | |||
39 | /** |
||
40 | * {@inheritdoc} |
||
41 | */ |
||
42 | 7 | public function equals(Embeddable $object) |
|
46 | |||
47 | /** |
||
48 | * {@inheritdoc} |
||
49 | */ |
||
50 | 14 | public function __toString() |
|
54 | |||
55 | /** |
||
56 | * @access public |
||
57 | * @return int |
||
58 | */ |
||
59 | 7 | public function getVersion() |
|
63 | |||
64 | /** |
||
65 | * @access public |
||
66 | * @return string |
||
67 | */ |
||
68 | 47 | public function getExpanded() |
|
78 | |||
79 | /** |
||
80 | * All leading zeros are removed. |
||
81 | * |
||
82 | * @access public |
||
83 | * @return string |
||
84 | */ |
||
85 | 7 | public function getAlternate() |
|
93 | |||
94 | /** |
||
95 | * All consecutive sections of zeroes are removed. |
||
96 | * |
||
97 | * @access public |
||
98 | * @return string |
||
99 | */ |
||
100 | 47 | public function getCondensed() |
|
101 | { |
||
102 | 47 | if ($this->version === 4) { |
|
103 | 2 | return $this->value; |
|
104 | } |
||
105 | |||
106 | 45 | $addr = preg_replace('/(^|:)0+(\d)/', '\1\2', $this->getExpanded()); |
|
107 | |||
108 | 45 | if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $addr, $matches, PREG_OFFSET_CAPTURE)) { |
|
109 | 45 | $max = 0; |
|
110 | 45 | $pos = null; |
|
111 | |||
112 | 45 | foreach ($matches[0] as $match) { |
|
113 | 45 | if (strlen($match[0]) > $max) { |
|
114 | 45 | $max = mb_strlen($match[0]); |
|
115 | 45 | $pos = $match[1]; |
|
116 | } |
||
117 | } |
||
118 | |||
119 | 45 | $addr = substr_replace($addr, '::', $pos, $max); |
|
120 | } |
||
121 | |||
122 | 45 | return $addr; |
|
123 | } |
||
124 | |||
125 | /** |
||
126 | * @access public |
||
127 | * @return string |
||
128 | */ |
||
129 | 7 | public function toLong() |
|
130 | { |
||
131 | 7 | if ($this->version === 4) { |
|
132 | 2 | return sprintf('%u', ip2long($this->value)); |
|
133 | } |
||
134 | |||
135 | 5 | $octet = 16 - 1; |
|
136 | 5 | $long = 0; |
|
137 | |||
138 | 5 | foreach (unpack('C*', inet_pton($this->value)) as $char) { |
|
139 | 5 | $long = bcadd($long, bcmul($char, bcpow(256, $octet--))); |
|
140 | } |
||
141 | |||
142 | 5 | return $long; |
|
143 | } |
||
144 | |||
145 | /** |
||
146 | * @access public |
||
147 | * @return string |
||
148 | */ |
||
149 | 7 | public function toHex() |
|
153 | |||
154 | /** |
||
155 | * @access public |
||
156 | * @return string |
||
157 | */ |
||
158 | 47 | public function toBinary() |
|
171 | } |
||
172 |