Complete reference of all public methods and classes in the IPv4 Subnet Calculator library v5.0.
- Main Classes
- Subnet Class
- SubnetParser Class
- Subnets Class
- SubnetAllocator Class
- Value Object Classes
- Enum Classes
Snippets assume the classes are imported (use IPv4\Subnet;, use IPv4\IPAddress;, use IPv4\SubnetMask;, and so on) and, unless a snippet defines its own, that $subnet is:
$subnet = new Subnet('192.168.1.100', 24);v5.0 introduces a clean object-oriented architecture:
Subnet- Main class for subnet operationsSubnetParser- Factory for creating subnets from various input formatsSubnets- Collection operations on arrays of Subnet objectsSubnetAllocator- Deterministic variable-size allocation within one parent networkIPAddress- Immutable IP address value objectSubnetMask- Immutable subnet mask value objectWildcardMask- Immutable wildcard mask value objectIPRange- Immutable IP range value object (iterable)ReverseDnsDelegation- Immutable RFC 2317 classless reverse-DNS delegation dataAllocationPlan- Immutable result of a subnet allocation
IPAddress, SubnetMask, WildcardMask and IPRange implement the Stringable interface. IPAddress, SubnetMask and WildcardMask also provide format methods (asQuads(), asHex(), etc.); SubnetMask and WildcardMask share them through the Mask interface.
IPv4\Subnet - Main entry point for subnet calculations. Immutable, provides access to all subnet information through value objects.
new Subnet(string|IPAddress $ipAddress, int $networkSize): SubnetCreate a subnet from IP address and prefix length.
Parameters:
$ipAddress- IP address in dotted decimal format, or anIPAddress$networkSize- CIDR prefix (0-32)
Example:
$subnet = new Subnet('192.168.1.100', 24);
$subnet = new Subnet(new IPAddress('192.168.1.100'), 24);Subnet::fromCidr(string $cidr): SubnetCreate a subnet from CIDR notation.
Parameters:
$cidr- CIDR notation (e.g., '192.168.1.0/24')
Example:
$subnet = Subnet::fromCidr('192.168.1.100/24');Subnet::fromNetworkCidr(string $cidr): SubnetCreate a subnet only when the input IP is its network address. Uses the same syntax validation and diagnostics as fromCidr(), then throws \InvalidArgumentException if host bits are set. Construction and fromCidr() continue to accept and retain host addresses.
For /0, only 0.0.0.0/0 is aligned. For /31, the input must be even; every valid /32 address is aligned. Runs in O(1) time and additional space.
Example:
$network = Subnet::fromNetworkCidr('192.168.1.0/24');
echo $network->cidr(); // 192.168.1.0/24
// Subnet::fromNetworkCidr('192.168.1.50/24') throws \InvalidArgumentException.ipAddress(): IPAddressReturns the input IP address as an IPAddress value object.
Example:
$ip = $subnet->ipAddress();
echo $ip; // "192.168.1.100"
echo $ip->asHex(); // "C0A80164"isNetworkAddress(): boolChecks whether the original input IP equals this subnet's network address. It does not validate an arbitrary string or change the stored input. Runs in O(1) time and additional space.
Example:
$host = Subnet::fromCidr('192.168.1.50/24');
\var_dump($host->isNetworkAddress()); // false
\var_dump(Subnet::fromNetworkCidr('192.168.1.0/24')->isNetworkAddress()); // truenetworkSize(): intReturns the CIDR prefix length (0-32).
Example:
$size = $subnet->networkSize(); // 24cidr(): stringReturns CIDR notation string with the input IP address.
Note: Returns the input IP with prefix. For canonical form suitable for string comparisons, use networkCidr() instead.
Example:
$subnet = Subnet::fromCidr('192.168.1.100/24');
$cidr = $subnet->cidr(); // "192.168.1.100/24"networkCidr(): stringReturns canonical CIDR notation using the network address.
Use this for:
- String comparisons between subnets
- Serialization and storage
- Scenarios where equal subnets must produce identical strings
Example:
$subnet1 = Subnet::fromCidr('192.168.1.100/24');
$subnet2 = Subnet::fromCidr('192.168.1.200/24');
$subnet1->cidr(); // "192.168.1.100/24"
$subnet2->cidr(); // "192.168.1.200/24"
$subnet1->networkCidr(); // "192.168.1.0/24"
$subnet2->networkCidr(); // "192.168.1.0/24"networkAddress(): IPAddressReturns the network address (first IP in subnet).
Example:
$network = $subnet->networkAddress(); // IPAddress: 192.168.1.0
echo $network->asQuads(); // "192.168.1.0"broadcastAddress(): IPAddressReturns the broadcast address (last IP in subnet).
Example:
$broadcast = $subnet->broadcastAddress(); // IPAddress: 192.168.1.255minHost(): IPAddressReturns the first usable host address.
Example:
$min = $subnet->minHost(); // IPAddress: 192.168.1.1maxHost(): IPAddressReturns the last usable host address.
Example:
$max = $subnet->maxHost(); // IPAddress: 192.168.1.254mask(): SubnetMaskReturns the subnet mask as a SubnetMask value object.
Example:
$mask = $subnet->mask();
echo $mask; // "255.255.255.0"
echo $mask->asBinary(); // "11111111111111111111111100000000"wildcardMask(): WildcardMaskReturns the wildcard mask (inverse of subnet mask) for use in Cisco ACLs.
Example:
$wildcard = $subnet->wildcardMask(); // WildcardMask: 0.0.0.255networkPortion(): IPAddressReturns the network portion of the input IP address.
Example:
$network = $subnet->networkPortion(); // IPAddress: 192.168.1.0hostPortion(): IPAddressReturns the host portion of the input IP address.
Example:
$host = $subnet->hostPortion(); // IPAddress: 0.0.0.100addressRange(): IPRangeReturns all IPs in the subnet (including network and broadcast) as an iterable IPRange.
Example:
$range = $subnet->addressRange();
foreach ($range as $ip) {
echo $ip . "\n"; // Iterate through all 256 IPs
}hostRange(): IPRangeReturns usable host IPs (excludes network and broadcast) as an iterable IPRange.
Note: For /31 networks (RFC 3021 point-to-point) and /32 networks (single host), all addresses are returned since these special-purpose networks don't reserve network/broadcast addresses.
Example:
$range = $subnet->hostRange();
foreach ($range as $ip) {
echo $ip . "\n"; // Iterate through 254 usable hosts
}addressCount(): intReturns total number of IP addresses in the subnet.
Example:
$total = $subnet->addressCount(); // 256hostCount(): intReturns number of usable host addresses.
Example:
$hosts = $subnet->hostCount(); // 254All classification methods delegate to the ipAddress() object, so they classify the input IP only, not the whole block.
A block that straddles a range boundary is classified by whichever side its input IP is on: 10.0.0.0/7 is private, but it also
spans the public 11.0.0.0/8. To check a whole block, test it against the range with isContainedIn() or overlaps().
isPrivate(): boolCheck if the IP is in private address space (RFC 1918).
isPublic(): boolCheck if the IP is public: not in any of the special-purpose ranges recognized by this library. Stricter than global reachability: a few special-purpose blocks are globally reachable but are not counted as public; see isGloballyReachable().
isLoopback(): boolCheck if the IP is in loopback range (127.0.0.0/8).
isLinkLocal(): boolCheck if the IP is link-local (169.254.0.0/16).
isMulticast(): boolCheck if the IP is multicast (224.0.0.0/4).
isCarrierGradeNat(): boolCheck if the IP is in carrier-grade NAT space (100.64.0.0/10).
isDocumentation(): boolCheck if the IP is reserved for documentation (RFC 5737).
isBenchmarking(): boolCheck if the IP is reserved for benchmarking (198.18.0.0/15).
isIetfProtocol(): boolCheck if the IP is reserved for IETF protocol assignments (192.0.0.0/24).
Used for protocols like DS-Lite, NAT64, and other IETF-assigned uses.
Links: RFC 5735, RFC 6890
is6to4Relay(): boolCheck if the IP is in the deprecated 6to4 relay anycast range (192.88.99.0/24).
This range is deprecated as of RFC 7526. The 6a44 relay anycast address 192.88.99.2 is excluded; it is classified by isIanaReserved().
Links: RFC 3068, RFC 7526
isIanaReserved(): boolCheck if the IP is in an IANA Special-Purpose Address Registry range.
Covers three /24 blocks: 192.31.196.0/24 (AS112-v4), 192.52.193.0/24 (AMT), 192.175.48.0/24 (Direct Delegation AS112), plus the 6a44 relay anycast address 192.88.99.2/32.
Links: RFC 7535, RFC 7450, RFC 7534, RFC 6751
isReserved(): boolCheck if the IP is in reserved address space (240.0.0.0/4).
isLimitedBroadcast(): boolCheck if the IP is the limited broadcast address (255.255.255.255).
isThisNetwork(): boolCheck if the IP is in "this network" range (0.0.0.0/8).
isGloballyReachable(): boolCheck if the IP is eligible for global unicast forwarding under the "Globally Reachable" column of the IANA IPv4 Special-Purpose Address Registry, using the most specific matching entry. Addresses outside the registry return true, except multicast (224.0.0.0/4), which returns false. A blank registry field, as on the deprecated 6to4 relay block 192.88.99.0/24, returns false: false includes "not established by this policy". This is address policy, not evidence of allocation, a route or live connectivity. isPublic() and addressType() are unaffected. Runs in O(1) time and additional space.
Example:
Subnet::fromCidr('192.0.0.9/32')->isGloballyReachable(); // true - PCP anycast
Subnet::fromCidr('192.0.0.9/32')->isPublic(); // false - still IETF protocol space
Subnet::fromCidr('192.0.0.8/32')->isGloballyReachable(); // false - IPv4 dummy address
Subnet::fromCidr('192.88.99.2/32')->isGloballyReachable(); // false - 6a44 relay is not reachableLinks: Global Reachability
addressType(): AddressTypeReturns the address type as an AddressType enum.
Example:
$type = $subnet->addressType(); // AddressType::PrivatenetworkClass(): NetworkClassReturns the classful network class (A, B, C, D, E).
defaultClassMask(): ?stringReturns the default subnet mask for the network class, or null for D/E.
defaultClassPrefix(): ?intReturns the default prefix for the network class, or null for D/E.
isClassful(): boolCheck if the subnet uses its default classful mask.
usableHostPercentage(): floatReturns percentage of usable addresses (host count / total count).
unusableAddressCount(): intReturns number of unusable addresses (network + broadcast, except /31 and /32).
utilizationFor(int $requiredHosts): floatCalculate utilization percentage for a given host requirement.
Throws \InvalidArgumentException if $requiredHosts is negative.
Example:
$utilization = $subnet->utilizationFor(100); // 39.37% for /24wastedAddressesFor(int $requiredHosts): intCalculate wasted addresses for a given host requirement.
Throws \InvalidArgumentException if $requiredHosts is negative.
Example:
$wasted = $subnet->wastedAddressesFor(100); // 154 for /24split(int $newPrefix): Subnet[]Split subnet into smaller subnets with the specified prefix.
Throws \InvalidArgumentException if $newPrefix is invalid.
Example:
$smaller = $subnet->split(26); // Split /24 into four /26 subnetssplitIterator(int $newPrefix): \Generator<int, Subnet>Lazy version of split() that yields one subnet at a time. Use for large splits. Throws on call for an invalid prefix.
subnetAt(int $newPrefix, int $index): SubnetReturns the child at a zero-based index in ascending network order, using O(1) time and additional space. The result is canonical even when the parent's input IP has host bits set.
The new prefix must be strictly greater than the parent prefix and at most 32, matching splitIterator(). A /32 has no child subnets. Invalid prefixes throw \InvalidArgumentException before index validation. Indices must be from 0 to 2^($newPrefix - $parentPrefix) - 1; negative or out-of-range indices throw \OutOfRangeException.
Examples:
$parent = Subnet::fromCidr('192.0.2.200/24');
echo $parent->subnetAt(26, 0)->cidr(); // 192.0.2.0/26
echo $parent->subnetAt(26, 3)->cidr(); // 192.0.2.192/26
echo Subnet::fromCidr('0.0.0.0/0')->subnetAt(32, 4_294_967_295)->cidr();
// 255.255.255.255/32, without traversing preceding childrensupernet(int $prefix): SubnetReturns the enclosing block at a shorter or equal prefix. The result is canonical (its input IP is the network address) even when this subnet's input IP has host bits set, and it always contains this subnet.
The prefix must be from 0 to the current prefix. A prefix equal to the current one returns the canonical form of this block, so generic code such as supernet(\min(16, $subnet->networkSize())) works for any subnet. Any other prefix throws \InvalidArgumentException with the message Supernet prefix must be between 0 and {current prefix}, got {prefix}.
Examples:
$subnet = Subnet::fromCidr('192.168.1.100/24');
echo $subnet->supernet(16)->cidr(); // 192.168.0.0/16
echo $subnet->supernet(24)->cidr(); // 192.168.1.0/24
echo $subnet->supernet(0)->cidr(); // 0.0.0.0/0
echo Subnet::fromCidr('10.0.0.5/32')->supernet(31)->cidr(); // 10.0.0.4/31
$subnet->supernet(25); // throws \InvalidArgumentExceptioncontains(Subnet $other): boolCheck if this subnet contains another subnet.
isContainedIn(Subnet $other): boolCheck if this subnet is contained within another subnet.
overlaps(Subnet $other): boolCheck if this subnet overlaps with another subnet.
isAdjacent(Subnet $other): boolReturns whether two disjoint full address ranges touch, in either order. Includes network and broadcast addresses, ignores input host bits, and permits unequal prefixes. Adjacency does not imply that blocks can aggregate; even same-prefix neighbors must be aligned siblings to merge. Gaps, overlap, containment and equality return false. Runs in O(1) time and additional space.
Example:
$left = Subnet::fromCidr('10.0.1.50/24');
$right = Subnet::fromCidr('10.0.2.20/24');
\var_dump($left->isAdjacent($right)); // true; these /24s cannot merge
\var_dump($right->isAdjacent($left)); // true
\var_dump($left->isAdjacent(Subnet::fromCidr('10.0.1.128/25'))); // false; contained
\var_dump(Subnet::fromCidr('255.255.255.255/32')->isAdjacent(Subnet::fromCidr('0.0.0.0/32'))); // false/0 has no adjacent block. Consecutive /31 or /32 blocks can be adjacent; the maximum IPv4 address never wraps to zero. See finding adjacent blocks.
intersection(Subnet $other): ?SubnetReturns null for disjoint blocks, including adjacent ones. Overlapping CIDR blocks are nested, so their intersection is the narrower block. The result always has a canonical input IP, including when equal networks were constructed with host bits. The result is symmetric by value. Runs in O(1) time and additional space, including /0, /31 and /32 at either IPv4 boundary.
Example:
$left = Subnet::fromCidr('192.168.1.50/24');
$right = Subnet::fromCidr('192.168.1.200/24');
$shared = $left->intersection($right);
echo $shared?->cidr() . "\n"; // 192.168.1.0/24
echo $shared?->ipAddress()->asQuads() . "\n"; // 192.168.1.0
\var_dump($left->intersection(Subnet::fromCidr('192.168.2.0/24'))); // nullSee restricting a block to a scope.
exclude(Subnet $exclude): Subnet[]Exclude a subnet, returning the remaining address space.
Example:
$remaining = $allocated->exclude($reserved);excludeAll(array $excludes): Subnet[]Exclude multiple subnets, returning the remaining address space. With an empty array, returns this subnet normalized to its network address.
Throws \InvalidArgumentException if any element is not a Subnet.
next(): SubnetGet the next adjacent subnet of the same size.
Throws \RuntimeException if the next subnet exceeds the IPv4 range.
Example:
$next = $subnet->next(); // 192.168.2.0/24previous(): SubnetGet the previous adjacent subnet of the same size.
Throws \RuntimeException if the previous subnet is below 0.0.0.0.
adjacent(int $count): Subnet[]Get adjacent subnets. Positive count for forward, negative for backward.
Throws \RuntimeException if the requested subnets exceed the IPv4 range.
Example:
$forward = $subnet->adjacent(3); // Next 3 subnets
$backward = $subnet->adjacent(-3); // Previous 3 subnetsadjacentIterator(int $count): \Generator<int, Subnet>Lazy version of adjacent() that yields one subnet at a time. Use for large counts. Throws on call if the requested subnets exceed the IPv4 range.
containsIP(string|IPAddress $ip): boolCheck if an IP address is within this subnet.
Throws \InvalidArgumentException if $ip is a string that is not a valid IPv4 address.
Example:
$inSubnet = $subnet->containsIP('192.168.1.100'); // trueequals(Subnet $other): boolCheck if two subnets are equal (same network and prefix).
compare(Subnet $other): intReturns exactly -1, 0 or 1, ordered by ascending numeric network address, then ascending prefix. At an equal start address, broader networks come first. Input host bits do not affect ordering; zero agrees with equals(). Runs in O(1) time and additional space.
Example:
\var_dump(Subnet::fromCidr('2.0.0.0/8')->compare(Subnet::fromCidr('10.0.0.0/8'))); // -1
\var_dump(Subnet::fromCidr('10.0.0.0/8')->compare(Subnet::fromCidr('10.0.0.0/16'))); // -1
\var_dump(Subnet::fromCidr('10.255.255.255/8')->compare(Subnet::fromCidr('10.0.0.0/8'))); // 0Use \usort($subnets, static fn (Subnet $a, Subnet $b): int => $a->compare($b)) to sort subnet objects. See the sorting example for canonical output.
arpaDomain(): stringGet the reverse DNS ARPA domain for the input IP address.
Example:
$subnet = Subnet::fromCidr('192.168.1.100/24');
$arpa = $subnet->arpaDomain(); // "100.1.168.192.in-addr.arpa"reverseZones(): array // list<string>Get the reverse DNS zone origins that exactly cover the network: the smallest set of octet-aligned in-addr.arpa zones, in ascending network order, without trailing dots. A prefix off an octet boundary splits to the next one, so a /20 yields sixteen /24 origins and a /25–/31 yields one /32 origin per address, never the enclosing /24. /0 yields in-addr.arpa. Input host bits are ignored. The names are calculated origins, not a claim that the caller controls those zones. Runs in time and memory proportional to the number of origins, at most 128.
Example:
Subnet::fromCidr('192.168.1.50/24')->reverseZones(); // ["1.168.192.in-addr.arpa"]
Subnet::fromCidr('172.16.0.0/15')->reverseZones(); // ["16.172.in-addr.arpa", "17.172.in-addr.arpa"]
Subnet::fromCidr('192.0.2.6/31')->reverseZones(); // ["6.2.0.192.in-addr.arpa", "7.2.0.192.in-addr.arpa"]classlessDelegation(?string $childLabel = null): ReverseDnsDelegationGet RFC 2317 classless reverse-DNS delegation data for a /25–/32 network: the enclosing /24 parent zone, the child zone origin, and one parent-zone CNAME per address. The child label defaults to startLastOctet-endLastOctet, such as 64-127. A custom label must be one nonnumeric label of 1–63 ASCII letters, digits or hyphens, beginning and ending with a letter or digit; numeric-only labels are rejected because they could collide with PTR owner names. Input host bits are ignored. Throws \InvalidArgumentException for /0–/24, checked first, and for an invalid label. Runs in time and memory proportional to the address count, at most 128 records.
Example:
$delegation = Subnet::fromCidr('192.0.2.64/26')->classlessDelegation();
$delegation->parentZone(); // "2.0.192.in-addr.arpa"
$delegation->childZone(); // "64-127.2.0.192.in-addr.arpa"
$delegation->cnameRecords()['65.2.0.192.in-addr.arpa']; // "65.64-127.2.0.192.in-addr.arpa"
Subnet::fromCidr('192.0.2.64/26')->classlessDelegation('cust1')->childZone(); // "cust1.2.0.192.in-addr.arpa"toArray(): arrayGet subnet information as an associative array.
toJson(): stringGet subnet information as JSON string.
toPrintable(): stringGet subnet information as a formatted text report.
__toString(): stringString representation in canonical CIDR notation using the network address, same as networkCidr() (e.g., "192.168.1.0/24"). Equal subnets have identical string forms. Use cidr() for the input IP with prefix, and toPrintable() for detailed formatted reports.
Example:
echo $subnet; // "192.168.1.0/24"
echo $subnet->toPrintable(); // Full formatted reportjsonSerialize(): arrayImplement JsonSerializable interface.
IPv4\SubnetParser - Static factory methods for creating Subnet objects from various input formats.
SubnetParser::fromMask(string|IPAddress $ipAddress, string|SubnetMask $subnetMask): SubnetCreate subnet from an IP address and subnet mask. Each argument may be a string or an IPAddress/SubnetMask object.
Throws \InvalidArgumentException if the subnet mask is invalid or non-contiguous.
Example:
$subnet = SubnetParser::fromMask('192.168.1.0', '255.255.255.0');SubnetParser::fromWildcardMask(string|IPAddress $ipAddress, string|WildcardMask $wildcardMask): SubnetCreate subnet from an IP address and wildcard mask. Each argument may be a string or an IPAddress/WildcardMask object.
Throws \InvalidArgumentException if the wildcard mask is invalid or non-contiguous.
Example:
$subnet = SubnetParser::fromWildcardMask('192.168.1.0', '0.0.0.255'); // 192.168.1.0/24SubnetParser::fromRange(string|IPAddress $startIp, string|IPAddress $endIp): SubnetCreate subnet from IP range (must be valid CIDR block). Each endpoint may be a string or an IPAddress.
Throws \InvalidArgumentException if the range does not represent a valid CIDR block.
For an arbitrary inclusive range that may require several blocks, use IPRange::toSubnets().
Example:
$subnet = SubnetParser::fromRange('192.168.1.0', '192.168.1.255');SubnetParser::fromHostCount(string|IPAddress $ipAddress, int $hostCount): SubnetCreate smallest subnet that accommodates the required host count. The address may be a string or an IPAddress.
Throws \InvalidArgumentException if the host count is invalid.
Example:
$subnet = SubnetParser::fromHostCount('192.168.1.0', 100); // Creates /25SubnetParser::optimalPrefixForHosts(int $hostCount): intCalculate optimal CIDR prefix for a given host count.
Throws \InvalidArgumentException if the host count is invalid.
Example:
$prefix = SubnetParser::optimalPrefixForHosts(100); // Returns 25IPv4\Subnets - Static methods for collection operations on arrays of Subnet objects.
Subnets::aggregate(array $subnets): Subnet[]Combine contiguous subnets into minimal set of larger blocks.
Throws \InvalidArgumentException if any element is not a Subnet.
Parameters:
$subnets- Array of Subnet objects
Returns: Array of Subnet objects
Example:
$aggregated = Subnets::aggregate([
Subnet::fromCidr('192.168.0.0/24'),
Subnet::fromCidr('192.168.1.0/24'),
]);
// Returns: [Subnet: 192.168.0.0/23]Subnets::summarize(array $subnets): SubnetFind smallest single CIDR block containing all input subnets.
Throws \InvalidArgumentException if the array is empty or any element is not a Subnet.
Parameters:
$subnets- Array of Subnet objects
Returns: Single Subnet object
Example:
$summary = Subnets::summarize([
Subnet::fromCidr('192.168.0.0/24'),
Subnet::fromCidr('192.168.1.0/24'),
]);
// Returns: Subnet: 192.168.0.0/23Subnets::longestPrefixMatch(array $subnets, string|IPAddress $ip): ?SubnetFind the most specific subnet containing an IP address: of the subnets whose range includes $ip, the one with the largest prefix (networkSize()). Host bits in the inputs are ignored, so 0.0.0.0/0 acts as a default route. When several containing subnets share the largest prefix, the first in iteration order wins.
The matching element itself is returned, not a canonical copy, so \array_search($match, $subnets, true) recovers its array key. This is a linear O(n) scan, not a routing trie.
Throws \InvalidArgumentException if any element is not a Subnet or the IP address is invalid.
Parameters:
$subnets- Array of Subnet objects, with any keys$ip- IP address to match (string or IPAddress)
Returns: The most specific containing Subnet from $subnets, or null if the array is empty or no subnet contains the address
Example:
$routes = [
Subnet::fromCidr('0.0.0.0/0'),
Subnet::fromCidr('10.0.0.0/8'),
Subnet::fromCidr('10.1.0.0/16'),
];
Subnets::longestPrefixMatch($routes, '10.1.2.3'); // Subnet: 10.1.0.0/16
Subnets::longestPrefixMatch($routes, '10.200.0.1'); // Subnet: 10.0.0.0/8
Subnets::longestPrefixMatch($routes, '8.8.8.8'); // Subnet: 0.0.0.0/0
Subnets::longestPrefixMatch([], '8.8.8.8'); // nullThese methods treat each array as the set of addresses its subnets cover, including network and broadcast addresses. Inputs may contain duplicate, nested, unsorted or adjacent subnets, with any array keys; host bits are ignored. Every element of both arrays is validated before any result is computed, so an invalid element throws \InvalidArgumentException even when the other array is empty. Inputs are sorted and merged into address intervals in O(n log n + m log m) time, then swept once; no addresses are enumerated. Results take additional time and space proportional to the number of returned blocks.
Subnets::intersection(array $left, array $right): Subnet[]Returns the addresses in both arrays as the fewest canonical CIDR blocks, in ascending order, with numeric keys. Commutative; intersection($a, $a) equals aggregate($a).
Example:
$shared = Subnets::intersection(
[Subnet::fromCidr('10.0.0.0/23'), Subnet::fromCidr('10.0.4.0/24')],
[Subnet::fromCidr('10.0.1.0/24'), Subnet::fromCidr('10.0.4.128/25')],
);
// Returns: [Subnet: 10.0.1.0/24, Subnet: 10.0.4.128/25]Subnets::difference(array $left, array $right): Subnet[]Returns the addresses in $left that are not in $right as the fewest canonical CIDR blocks, in ascending order, with numeric keys. Not commutative. Together, difference($a, $b) and intersection($a, $b) cover exactly the addresses of $a. For a single base subnet, Subnet::excludeAll() gives the same blocks.
Example:
$free = Subnets::difference(
[Subnet::fromCidr('10.0.0.0/23'), Subnet::fromCidr('10.0.4.0/24')],
[Subnet::fromCidr('10.0.0.0/24'), Subnet::fromCidr('10.0.1.128/26'), Subnet::fromCidr('10.0.4.0/25')],
);
// Returns: [Subnet: 10.0.1.0/25, Subnet: 10.0.1.192/26, Subnet: 10.0.4.128/25]Subnets::covers(array $covering, array $required): boolReturns whether every address in $required is in $covering, equivalent to difference($required, $covering) === []. Several smaller blocks may together cover a larger one. Every array covers []; [] covers no nonempty array.
Example:
$halves = [Subnet::fromCidr('192.0.2.0/25'), Subnet::fromCidr('192.0.2.128/25')];
Subnets::covers($halves, [Subnet::fromCidr('192.0.2.0/24')]); // true
Subnets::covers([], [Subnet::fromCidr('192.0.2.1/32')]); // falseUnion needs no separate method: use Subnets::aggregate([...\array_values($left), ...\array_values($right)]), so duplicate string keys cannot overwrite an input block.
IPv4\SubnetAllocator - Stateless, deterministic variable-size (VLSM) allocation within one parent network.
SubnetAllocator::allocate(Subnet $parent, array $requirements, array $reserved = []): AllocationPlanAllocate one CIDR block per named requirement from $parent, avoiding $reserved, and return an AllocationPlan.
Each host count is sized as by optimalPrefixForHosts(): 1 gives a /32, 2 a /31, and larger counts include network and broadcast addresses. Larger blocks are placed first, equal sizes in bytewise name order (strcmp()); each takes the lowest aligned free address where it fits. The parent's host bits are ignored. Reservations may be duplicated, nested, overlapping or keyed, but must each lie wholly inside the parent. With no requirements, the plan is the parent minus the reservations; reserving the entire parent is then valid.
Requirement names are array keys: PHP keeps only the last duplicate key, so reject duplicates while building the map, and it converts numeric strings such as '10' to integers, which are rejected.
All input is validated before anything is placed. Throws \InvalidArgumentException if a name is not a nonempty string, a host count is not an int accepted by optimalPrefixForHosts(), or a reservation is not a Subnet contained in the parent. Throws \RuntimeException naming the first requirement, in placement order, that no free block can hold, with its prefix, the largest free block and the free address count; fragmentation can cause this even when enough addresses are free in total. No partial plan is returned. Runs in time proportional to the number of requirements times the number of free blocks, plus sorting, independent of the parent's address count; no addresses are enumerated.
Parameters:
$parent- Network to allocate from$requirements-array<string, int>: name => required usable hosts$reserved- Array of Subnet objects to keep free of allocations
Returns: AllocationPlan
Example:
$plan = SubnetAllocator::allocate(
Subnet::fromCidr('10.0.0.0/22'),
['Branch' => 50, 'HQ' => 500],
[Subnet::fromCidr('10.0.3.0/24')],
);
$plan->allocations(); // ['Branch' => Subnet: 10.0.2.0/26, 'HQ' => Subnet: 10.0.0.0/23]
$plan->reserved(); // [Subnet: 10.0.3.0/24]
$plan->remaining(); // [Subnet: 10.0.2.64/26, Subnet: 10.0.2.128/25]
SubnetAllocator::allocate(Subnet::fromCidr('10.0.0.0/24'), ['a' => 200, 'b' => 100]);
// Throws \RuntimeException: Cannot allocate 'b' as a /25: no free space remainsSubnetAllocator::allocateByPrefix(Subnet $parent, array $prefixes, array $reserved = []): AllocationPlanAllocate one CIDR block per named prefix from $parent, avoiding $reserved, and return an AllocationPlan.
Use this when a block's size is known as a prefix rather than a host count. Host-count sizing maps 2 hosts to a /31 and 3 to a /29, so a /30 link can only be requested by prefix. To mix both sizings, convert host counts with optimalPrefixForHosts(): ['lan' => SubnetParser::optimalPrefixForHosts(50), 'wan' => 30].
Placement, ordering, reservations and names behave exactly as in allocate(): larger blocks (smaller prefixes) first, equal prefixes in bytewise name order, each at the lowest aligned free address; allocations are returned in input order. For equivalent input, allocate($parent, $hosts, $reserved) and allocateByPrefix($parent, array_map(SubnetParser::optimalPrefixForHosts(...), $hosts), $reserved) return the same plan.
All input is validated before anything is placed. Throws \InvalidArgumentException if a name is not a nonempty string, a prefix is not an int (Requirement 'wan' prefix must be an int, got string) or lies outside 0–32 (Requirement 'wan' prefix must be between 0 and 32, got 33), or a reservation is not a Subnet contained in the parent. A prefix shorter than the parent's is valid input that cannot fit: like any block that no free space can hold, it throws \RuntimeException naming the first such block in placement order. No partial plan is returned.
Parameters:
$parent- Network to allocate from$prefixes-array<string, int>: name => CIDR prefix (0–32)$reserved- Array of Subnet objects to keep free of allocations
Returns: AllocationPlan
Example:
$plan = SubnetAllocator::allocateByPrefix(
Subnet::fromCidr('192.168.0.0/24'),
['lan' => SubnetParser::optimalPrefixForHosts(50), 'wan' => 30],
);
$plan->allocations(); // ['lan' => Subnet: 192.168.0.0/26, 'wan' => Subnet: 192.168.0.64/30]
$plan->remaining(); // [Subnet: 192.168.0.68/30, Subnet: 192.168.0.72/29, Subnet: 192.168.0.80/28, Subnet: 192.168.0.96/27, Subnet: 192.168.0.128/25]
SubnetAllocator::allocateByPrefix(Subnet::fromCidr('10.0.0.0/24'), ['x' => 23]);
// Throws \RuntimeException: Cannot allocate 'x' as a /23: largest free block is a /24 (256 free addresses in 1 block)All value objects are immutable (readonly). IPAddress, SubnetMask, WildcardMask and IPRange implement Stringable and JsonSerializable, so they can be placed directly in a json_encode() payload. ReverseDnsDelegation and AllocationPlan implement JsonSerializable but not Stringable.
IPv4\IPAddress - Immutable IPv4 address value object.
new IPAddress(string|int $ipAddress): IPAddressCreate an IP address from dotted decimal format or its unsigned 32-bit integer value.
A string is always parsed as dotted decimal, so a numeric string such as '3232235876' is rejected.
Throws \InvalidArgumentException if the string is not a valid IPv4 address or the integer is outside 0 to 4294967295.
Example:
$ip = new IPAddress('192.168.1.100');
$ip = new IPAddress(3232235876); // 192.168.1.100IPAddress::fromInteger(int $integer): IPAddressCreate an IP address from its unsigned 32-bit integer value (the inverse of asInteger()).
Equivalent to new IPAddress($integer).
Throws \InvalidArgumentException if the integer is outside 0 to 4294967295.
Example:
$ip = IPAddress::fromInteger(3232235876); // 192.168.1.100
$next = IPAddress::fromInteger($ip->asInteger() + 1); // 192.168.1.101All format methods are provided via the Formattable trait:
asQuads(): stringReturns IP in dotted decimal format.
Example: "192.168.1.100"
asArray(): string[]Returns array of octet strings.
Example: ['192', '168', '1', '100']
asHex(): stringReturns IP in hexadecimal format.
Example: "C0A80164"
asBinary(): stringReturns IP in binary format.
Example: "11000000101010000000000101100100"
asInteger(): intReturns IP as 32-bit integer.
Example: 3232235876
__toString(): stringReturns IP in dotted decimal format (same as asQuads()).
jsonSerialize(): stringImplement JsonSerializable interface. Encodes as dotted decimal format (same as asQuads()).
Example:
\json_encode($subnet->networkAddress()); // "192.168.1.0"See Subnet Classification - same methods available on IPAddress.
arpaDomain(): stringGet reverse DNS ARPA domain.
Example:
$arpa = $ip->arpaDomain(); // "100.1.168.192.in-addr.arpa"networkClass(): NetworkClassGet the classful network class.
equals(IPAddress $other): boolCompare with another IPAddress.
compare(IPAddress $other): intOrder addresses by unsigned 32-bit integer value. Returns -1 if this address is lower, 0 if equal, 1 if higher; usable as a usort() callback.
Example:
$addresses = [new IPAddress('192.168.0.1'), new IPAddress('10.0.0.0'), new IPAddress('9.255.255.255')];
usort($addresses, fn (IPAddress $a, IPAddress $b): int => $a->compare($b));
// 9.255.255.255, 10.0.0.0, 192.168.0.1next(): IPAddressGet the following address, carrying across octet boundaries. Returns a new instance.
Throws \RuntimeException if the address is 255.255.255.255.
Example:
$next = (new IPAddress('10.0.0.255'))->next(); // 10.0.1.0previous(): IPAddressGet the preceding address, borrowing across octet boundaries. Returns a new instance.
Throws \RuntimeException if the address is 0.0.0.0.
Example:
$previous = (new IPAddress('10.0.1.0'))->previous(); // 10.0.0.255IPv4\SubnetMask - Immutable subnet mask value object.
new SubnetMask(int $prefix): SubnetMaskExample:
$mask = new SubnetMask(24); // Creates 255.255.255.0prefix(): intReturns the CIDR prefix length.
wildcardMask(): WildcardMaskReturns the corresponding wildcard mask.
equals(SubnetMask $other): boolCompare with another SubnetMask.
Same as IPAddress: asQuads(), asArray(), asHex(), asBinary(), asInteger(), __toString(), jsonSerialize()
IPv4\WildcardMask - Immutable wildcard mask value object (inverse of subnet mask).
new WildcardMask(int $prefix): WildcardMaskExample:
$wildcard = new WildcardMask(24); // Creates 0.0.0.255WildcardMask::fromString(string $wildcardMask): WildcardMaskCreate a wildcard mask from dotted-quad notation.
Throws \InvalidArgumentException if the mask is not a valid dotted quad or is non-contiguous. Non-contiguous ACL wildcards such as 0.0.255.0 are rejected because they do not describe a single subnet; see Wildcard Mask.
Example:
$wildcard = WildcardMask::fromString('0.0.0.255');
$wildcard->prefix(); // 24prefix(): intReturns the CIDR prefix length.
subnetMask(): SubnetMaskReturns the corresponding subnet mask.
equals(WildcardMask $other): boolCompare with another WildcardMask.
Same as IPAddress: asQuads(), asArray(), asHex(), asBinary(), asInteger(), __toString(), jsonSerialize()
IPv4\Mask - Common interface implemented by SubnetMask and WildcardMask. Extends Stringable and JsonSerializable.
prefix(): int
asQuads(): string
asArray(): string[]
asHex(): string
asBinary(): string
asInteger(): intUse it as a type hint when a function accepts either kind of mask:
function describe(IPv4\Mask $mask): string
{
return "/{$mask->prefix()} = {$mask->asQuads()}";
}
describe($subnet->mask()); // '/24 = 255.255.255.0'
describe($subnet->wildcardMask()); // '/24 = 0.0.0.255'IPv4\IPRange - Immutable IP range value object. Implements IteratorAggregate, Countable, JsonSerializable, and Stringable.
Interface Support:
IteratorAggregate- Useforeachto iterate over all IP addresses in the rangeCountable- Use PHP'scount()function to get the number of IPsJsonSerializable- Encodes as{"start": ..., "end": ...}Stringable- Automatically converts to "start - end" format
new IPRange(string|IPAddress $start, string|IPAddress $end): IPRangeEach address may be a dotted-quad string or an IPAddress, in any combination. IPAddress instances are stored as given, so start() and end() return the same objects.
Throws \InvalidArgumentException if either string is not a valid IPv4 address, or if start is greater than end.
Examples:
$range = new IPRange(
new IPAddress('192.168.1.0'),
new IPAddress('192.168.1.255')
);
$pool = new IPRange('192.168.10.100', '192.168.10.199'); // 100 addresses
$mixed = new IPRange('10.0.0.1', new IPAddress('10.0.0.10'));
new IPRange('192.168.1.100', '192.168.1.50'); // InvalidArgumentException: Start IP '192.168.1.100' is greater than end IP '192.168.1.50'
new IPRange('10.0.0.1', '10.0.0.256'); // InvalidArgumentException: Invalid IPv4 address: '10.0.0.256'start(): IPAddressReturns the starting IP address.
end(): IPAddressReturns the ending IP address.
count(): intReturns the number of IPs in the range. Because IPRange implements Countable, you can use either the count() method or PHP's built-in count() function.
Examples:
// Using the method
$count = $range->count(); // 256
// Using PHP's \count() function (recommended)
$count = \count($range); // 256at(int $index): IPAddressReturns the address at a zero-based index in O(1) time and additional space. Index 0 is the range's start, and count() - 1 is its end. Negative indices and indices greater than or equal to count() throw \OutOfRangeException.
Examples:
$hosts = Subnet::fromCidr('192.0.2.0/30')->hostRange();
echo $hosts->at(0); // 192.0.2.1, the first usable host
echo $hosts->at($hosts->count() - 1); // 192.0.2.2
$all = Subnet::fromCidr('0.0.0.0/0')->addressRange();
echo $all->at(4_294_967_295); // 255.255.255.255The existing host-range rules apply: /31 includes both addresses, and /32 includes its single address.
indexOf(string|IPAddress $ip): ?intReturns the address's zero-based index in O(1) time and additional space, or null for a valid IPv4 address outside the range. Malformed strings throw \InvalidArgumentException. For every valid index, $range->indexOf($range->at($index)) === $index.
Examples:
$hosts = Subnet::fromCidr('192.0.2.0/30')->hostRange();
$hosts->indexOf('192.0.2.1'); // 0
$hosts->indexOf(new IPAddress('192.0.2.2')); // 1
$hosts->indexOf('192.0.2.0'); // null (network address outside this host range)Use !== null to distinguish an address at index 0 from an address outside the range.
contains(string|IPAddress $ip): boolCheck if an IP is within the range.
Throws \InvalidArgumentException if $ip is a string that is not a valid IPv4 address.
contains() checks a single address. To compare two ranges, use containsRange(), overlaps(), intersection() or isAdjacent() below.
The range relations take an IPRange only, not a Subnet. Convert a subnet with $subnet->addressRange() (every address, network to broadcast) or $subnet->hostRange() (usable hosts only; for /31 and /32 this is the same as the address range). All four compare the range endpoints in O(1) time and never throw.
containsRange(IPRange $other): boolCheck if every address of $other is within this range. Containment is inclusive: a range contains itself, and shared endpoints count.
Examples:
$scope = Subnet::fromCidr('192.168.10.0/24')->hostRange(); // 192.168.10.1 - 192.168.10.254
$scope->containsRange(new IPRange('192.168.10.150', '192.168.10.250')); // true
$scope->containsRange(new IPRange('192.168.10.150', '192.168.10.255')); // false (includes the broadcast address)
$p2p = Subnet::fromCidr('192.0.2.6/31')->addressRange();
$p2p->containsRange(new IPRange('192.0.2.7', '192.0.2.7')); // true (a /32 inside a /31)overlaps(IPRange $other): boolCheck if the two ranges share at least one address. Symmetric; a single shared endpoint counts, but touching ranges (one ends just before the other starts) do not overlap.
Examples:
$engineering = new IPRange('192.168.10.100', '192.168.10.199');
$engineering->overlaps(new IPRange('192.168.10.150', '192.168.10.250')); // true
$engineering->overlaps(new IPRange('192.168.10.200', '192.168.10.250')); // false (touching, not overlapping)intersection(IPRange $other): ?IPRangeReturn the addresses shared by both ranges, from the larger start to the smaller end, or null if the ranges are disjoint. Unlike Subnet::intersection(), the result need not be either input: partially overlapping ranges give the overlapping part.
Examples:
$engineering = new IPRange('192.168.10.100', '192.168.10.199');
$sales = new IPRange('192.168.10.150', '192.168.10.250');
echo $engineering->intersection($sales); // 192.168.10.150 - 192.168.10.199
$engineering->intersection(new IPRange('192.168.11.10', '192.168.11.254')); // null
// A single shared address gives a one-address range
echo (new IPRange('192.0.2.0', '192.0.2.8'))->intersection(new IPRange('192.0.2.8', '192.0.2.15')); // 192.0.2.8 - 192.0.2.8isAdjacent(IPRange $other): boolCheck if the two ranges are disjoint and contiguous: one ends immediately before the other starts, in either order. Overlapping and identical ranges are not adjacent, matching Subnet::isAdjacent(). The address space does not wrap, so a range ending at 255.255.255.255 is not adjacent to one starting at 0.0.0.0.
Examples:
$first = new IPRange('192.168.20.10', '192.168.20.99');
$second = new IPRange('192.168.20.100', '192.168.20.199');
$first->isAdjacent($second); // true
$second->isAdjacent($first); // true
// Consecutive /32s and /31s are adjacent
(new IPRange('192.0.2.7', '192.0.2.7'))->isAdjacent(new IPRange('192.0.2.8', '192.0.2.8')); // true
(new IPRange('192.0.2.6', '192.0.2.7'))->isAdjacent(new IPRange('192.0.2.8', '192.0.2.9')); // true
(new IPRange('0.0.0.0', '0.0.0.0'))->isAdjacent(new IPRange('255.255.255.255', '255.255.255.255')); // false (no wrap)equals(IPRange $other): boolCompare with another IPRange.
getIterator(): \Generator<IPAddress>Get iterator for foreach loops. Because IPRange implements IteratorAggregate, you can iterate directly without calling this method explicitly.
Examples:
// Using foreach (recommended)
foreach ($range as $ip) {
echo $ip . "\n";
}
// Or access the iterator directly
$iterator = $range->getIterator();toArray(): IPAddress[]Convert to array of IPAddress objects. Caution: Memory-intensive for large ranges.
toSubnets(): array // list<Subnet>Return the smallest exact CIDR cover of the inclusive range. The numerically indexed list contains canonical, disjoint subnets sorted by ascending network address, with no gaps or addresses outside the range.
Unlike Subnets::summarize(), this never adds addresses. SubnetParser::fromRange() still requires a range that represents exactly one aligned CIDR block.
$range = new IPRange(new IPAddress('192.0.2.1'), new IPAddress('192.0.2.6'));
$cidrs = \array_map(static fn (Subnet $subnet): string => $subnet->cidr(), $range->toSubnets());
// ['192.0.2.1/32', '192.0.2.2/31', '192.0.2.4/31', '192.0.2.6/32']A singleton returns one /32; the full range 0.0.0.0–255.255.255.255 returns one 0.0.0.0/0. Addresses are not enumerated: work is proportional to the output block count times the fixed 32-bit width, and memory is proportional to the output block count.
__toString(): stringReturns range as "start - end" format.
Example: "192.168.1.0 - 192.168.1.255"
jsonSerialize(): array{start: string, end: string}Implement JsonSerializable interface. Encodes only the start and end addresses, not every IP in the range.
Example:
\json_encode($subnet->hostRange()); // {"start":"192.168.1.1","end":"192.168.1.254"}IPv4\ReverseDnsDelegation - Immutable RFC 2317 classless delegation data for a /25–/32 block. Implements JsonSerializable. All names omit trailing dots. NS, SOA and PTR records, parent-zone cooperation and DNS publishing remain the caller's responsibility.
new ReverseDnsDelegation(Subnet $subnet, ?string $childLabel = null): ReverseDnsDelegationUsually obtained via Subnet::classlessDelegation(), which takes the same arguments and throws the same exceptions.
parentZone(): stringThe enclosing /24 reverse zone, which publishes the CNAME records, e.g., "2.0.192.in-addr.arpa".
childZone(): stringThe delegated child zone origin, one label below the parent, e.g., "64-127.2.0.192.in-addr.arpa".
cnameRecords(): array // array<string, string>: owner => targetOne record per address in ascending address order, network and broadcast included: delegation describes address space, not usable hosts. Each owner is the address's PTR name in the parent zone; each target is the same last-octet label in the child zone.
Subnet::fromCidr('192.0.2.6/31')->classlessDelegation()->cnameRecords();
// [
// "6.2.0.192.in-addr.arpa" => "6.6-7.2.0.192.in-addr.arpa",
// "7.2.0.192.in-addr.arpa" => "7.6-7.2.0.192.in-addr.arpa",
// ]jsonSerialize(): array{parent_zone: string, child_zone: string, cname_records: array<string, string>}Implement JsonSerializable interface. Encodes the parent zone, the child zone and the CNAME records (owner => target, in the same order as cnameRecords()).
Example:
\json_encode(Subnet::fromCidr('192.0.2.6/31')->classlessDelegation());
// {"parent_zone":"2.0.192.in-addr.arpa","child_zone":"6-7.2.0.192.in-addr.arpa","cname_records":{"6.2.0.192.in-addr.arpa":"6.6-7.2.0.192.in-addr.arpa","7.2.0.192.in-addr.arpa":"7.6-7.2.0.192.in-addr.arpa"}}IPv4\AllocationPlan - Immutable result of SubnetAllocator::allocate() or allocateByPrefix(). Its allocations, reservations and remaining space are disjoint and together cover exactly the parent network. All subnets are canonical. Implements JsonSerializable.
Obtain plans from SubnetAllocator::allocate() or allocateByPrefix(). The constructor is internal. It checks only the shape of its arguments, throwing \InvalidArgumentException if an allocation key is not a string, the reserved or remaining array is not a list, or any element is not a Subnet. It does not check that the parts are disjoint, canonical or cover a parent network; only plans from allocate() or allocateByPrefix() are guaranteed to.
allocations(): array // array<string, Subnet>: name => subnetOne allocated subnet per requirement, in the caller's requirement order.
reserved(): array // list<Subnet>The union of the reservations as the fewest CIDR blocks, in ascending order.
remaining(): array // list<Subnet>The free space left after reservations and allocations as the fewest CIDR blocks, in ascending order.
$plan = SubnetAllocator::allocate(Subnet::fromCidr('192.0.2.0/29'), ['link' => 2], [Subnet::fromCidr('192.0.2.0/31')]);
$plan->allocations(); // ['link' => Subnet: 192.0.2.2/31]
$plan->remaining(); // [Subnet: 192.0.2.4/30]jsonSerialize(): array // array<string, mixed>: allocations, reserved, remainingImplement JsonSerializable interface. Encodes each subnet as its network CIDR string rather than a full subnet report: allocations as an object of name => CIDR in requirement order, and reserved and remaining as lists of CIDRs in ascending order. allocations is always a JSON object, {} when the plan has no allocations. Each CIDR parses back with Subnet::fromNetworkCidr().
Example:
\json_encode($plan, JSON_UNESCAPED_SLASHES);
// {"allocations":{"link":"192.0.2.2/31"},"reserved":["192.0.2.0/31"],"remaining":["192.0.2.4/30"]}
\json_encode(SubnetAllocator::allocate(Subnet::fromCidr('10.0.0.0/24'), []), JSON_UNESCAPED_SLASHES);
// {"allocations":{},"reserved":[],"remaining":["10.0.0.0/24"]}IPv4\AddressType - Enum for IP address types.
Values:
AddressType::Private- RFC 1918 private addressesAddressType::Public- Addresses not in any special-purpose rangeAddressType::Loopback- 127.0.0.0/8 loopback addressesAddressType::LinkLocal- 169.254.0.0/16 link-local/APIPA addressesAddressType::Multicast- 224.0.0.0/4 multicast addressesAddressType::CarrierGradeNat- 100.64.0.0/10 CGN shared address spaceAddressType::Documentation- RFC 5737 TEST-NET rangesAddressType::Benchmarking- RFC 2544 benchmarking addressesAddressType::IetfProtocol- RFC 5735/6890 IETF protocol assignments (192.0.0.0/24)AddressType::Deprecated6to4- RFC 3068/7526 deprecated 6to4 relay (192.88.99.0/24)AddressType::Reserved- 240.0.0.0/4 reserved for future useAddressType::LimitedBroadcast- 255.255.255.255 limited broadcastAddressType::IanaReserved- IANA Special-Purpose assignments (192.31.196.0/24, 192.52.193.0/24, 192.175.48.0/24, 192.88.99.2/32)AddressType::ThisNetwork- 0.0.0.0/8 "this" network
IPv4\NetworkClass - Enum for classful network classes.
Values:
NetworkClass::ANetworkClass::BNetworkClass::CNetworkClass::DNetworkClass::E
Methods:
getDefaultMask(): ?stringReturns the default classful subnet mask ('255.0.0.0', '255.255.0.0', '255.255.255.0'), or null for classes D and E.
getDefaultPrefix(): ?intReturns the default classful prefix (8, 16 or 24), or null for classes D and E.
Example:
$class = IPv4\Subnet::fromCidr('172.16.0.0/12')->networkClass(); // NetworkClass::B
$class->getDefaultMask(); // '255.255.0.0'
$class->getDefaultPrefix(); // 16See Migration Guide for detailed information on migrating from version 4.x to 5.0.
- Getting Started - Basic usage and examples
- Core Features - Common operations
- Advanced Features - Complex operations
- Examples - Real-world use cases