index/src/Net/IPAddress.php

82 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);
}
}