luka/network-address-types

提供网络地址的类型的值对象(IP v4/v6 和 MAC)

1.1.1 2023-03-22 12:00 UTC

This package is auto-updated.

Last update: 2024-09-22 15:26:28 UTC


README

Test Coverage Maintainability Infection MSI

此库提供了处理最常见的网络地址的类型。以下地址类型被支持

  • 以下形式的 MAC 地址
    • 冒号分隔(00:00:00:00:00:00
    • 破折号分隔(00-00-00-00-00-00
    • 无分隔符(000000000000
  • IPv4(例如:127.0.0.1
  • IPv6(例如:::1
  • IPv4 和 IPv6 的 CIDR 地址(例如:129.0.0.1/12ff80:e::/64

安装

可以使用 composer 执行安装

composer require luka/network-address-types

要求

  • PHP
    • 7.4(直到版本 1.1.0)
    • 8.0
    • 8.1
    • 8.2
  • 用于处理 IPv6 计算的 ext-gmp
  • 作为它通过实现 JSONSerializable 支持了 json_encode 的 ext-json

入门指南

use LUKA\Network\NetworkAddress;

$address = NetworkAddress::fromString('127.0.0.1');
assert($address instanceof \LUKA\Network\IPv4\IPv4Address);
$address = NetworkAddress::fromString('127.0.0.1/8');
assert($address instanceof \LUKA\Network\IPv4\CIDRv4Address);
$address = NetworkAddress::fromString('::1');
assert($address instanceof \LUKA\Network\IPv6\IPv6Address);
$address = NetworkAddress::fromString('ff80::1/64');
assert($address instanceof \LUKA\Network\IPv6\CIDRv6Address);
$address = NetworkAddress::fromString('84:34:ff:ff:ff:ff');
assert($address instanceof \LUKA\Network\MACAddress);

序列化

所有类型都可以从字符串构建,因此也可以使用 toString() 方法转换为字符串。

use LUKA\Network\NetworkAddress;

assert('::1' === NetworkAddress::fromString('::1')->toString());

在将地址转换为字符串时,它们将根据相应的类型进行归一化

use LUKA\Network\NetworkAddress;

assert('::1' === NetworkAddress::fromString('0:0:0:0::1')->toString());
assert('00:00:00:00:00:00' === NetworkAddress::fromString('00-00-00-00-00-00')->toString());

JSON

所有地址类型都实现了 JSONSerializable 接口,因此可以直接与 json_encode() 一起使用。

二进制

IP 和 MAC 地址也可以转换为相应的字节序列。 (例如,将它们存储在 BINARY 数据库字段中)。

它们也可以使用对应类的静态 fromByteString() 方法从字节序列构建。

地址比较

比较相等

每个地址都实现了一个 equals() 方法来与其他网络地址进行比较。

当地址来自同一类型且包含相同的值时,它们被视为相等

use LUKA\Network\NetworkAddress;

assert(
    true === NetworkAddress::fromString('::1')
        ->equals(NetworkAddress::fromString('::1'))
);

// Value mismatch:
assert(
    false === NetworkAddress::fromString('::1')
        ->equals(NetworkAddress::fromString('::2'))
);

// Type mismatch (different IP version):
assert(
    false === NetworkAddress::fromString('::1')
        ->equals(NetworkAddress::fromString('127.0.0.1'))
);

// Type mismatch (cidr vs non-cidr)
assert(
    false === NetworkAddress::fromString('192.168.0.5')
        ->equals(NetworkAddress::fromString('192.168.0.5/24'))
);

比较地址与网络

CIDR 地址允许获取对应于指定地址的网络。使用此网络,您可以检查 IP 地址是否在此网络中。

use LUKA\Network\NetworkAddress;

$cidr = NetworkAddress::fromString('192.168.0.7/8');
$network = $cidr->toNetwork();

assert(true === $network->containsAddress(NetworkAddress::fromString('192.168.0.1')));
assert(true === $network->containsAddress(NetworkAddress::fromString('192.45.0.2')));
assert(false === $network->containsAddress(NetworkAddress::fromString('127.10.0.1')));
assert(false === $network->containsAddress(NetworkAddress::fromString('ff80::5')));

这也适用于 IPv6

use LUKA\Network\NetworkAddress;

$cidr = NetworkAddress::fromString('ff80::/64');
$network = $cidr->toNetwork();

assert(true === $network->containsAddress(NetworkAddress::fromString('ff80::1')));
assert(true === $network->containsAddress(NetworkAddress::fromString('ff80::10:e5:7')));
assert(false === $network->containsAddress(NetworkAddress::fromString('ff80:e::1')));
assert(false === $network->containsAddress(NetworkAddress::fromString('127.0.0.1')));