81 lines
2 KiB
PHP
81 lines
2 KiB
PHP
<?php
|
|
// IPAddress.php
|
|
// Created: 2021-04-26
|
|
// Updated: 2022-02-27
|
|
|
|
namespace Index\Net;
|
|
|
|
use InvalidArgumentException;
|
|
use JsonSerializable;
|
|
use Stringable;
|
|
use Index\IEquatable;
|
|
|
|
final class IPAddress implements JsonSerializable, Stringable, IEquatable {
|
|
public const UNKNOWN = 0;
|
|
public const V4 = 4;
|
|
public const V6 = 6;
|
|
|
|
private string $raw;
|
|
private int $width;
|
|
|
|
public function __construct(string $raw) {
|
|
$this->raw = $raw;
|
|
$this->width = strlen($raw);
|
|
}
|
|
|
|
public function getRaw(): string {
|
|
return $this->raw;
|
|
}
|
|
public function getWidth(): int {
|
|
return $this->width;
|
|
}
|
|
|
|
public function getAddress(): string {
|
|
return sprintf($this->isV6() ? '[%s]' : '%s', inet_ntop($this->raw));
|
|
}
|
|
public function getCleanAddress(): string {
|
|
return inet_ntop($this->raw);
|
|
}
|
|
|
|
public function getVersion(): int {
|
|
if($this->isV4())
|
|
return self::V4;
|
|
if($this->isV6())
|
|
return self::V6;
|
|
return self::UNKNOWN;
|
|
}
|
|
|
|
public function isV4(): bool {
|
|
return $this->width === 4;
|
|
}
|
|
public function isV6(): bool {
|
|
return $this->width === 16;
|
|
}
|
|
|
|
public function __toString(): string {
|
|
return inet_ntop($this->raw);
|
|
}
|
|
|
|
public function equals(mixed $other): bool {
|
|
return $other instanceof IPAddress && $this->getRaw() === $other->getRaw();
|
|
}
|
|
|
|
public function jsonSerialize(): mixed {
|
|
return inet_ntop($this->raw);
|
|
}
|
|
|
|
public function __serialize(): array {
|
|
return [$this->raw];
|
|
}
|
|
public function __unserialize(array $serialized): void {
|
|
$this->raw = $serialized[0];
|
|
$this->width = strlen($this->raw);
|
|
}
|
|
|
|
public static function parse(string $address): self {
|
|
$parsed = inet_pton($address);
|
|
if($parsed === false)
|
|
throw new InvalidArgumentException('$address is not a valid IP address.');
|
|
return new static($parsed);
|
|
}
|
|
}
|