-
Notifications
You must be signed in to change notification settings - Fork 26
Home
IPv4/IPv6 manipulation library for PHP. This library (and documentation) is heavily inspired by Python ipaddress.
Feel free to read the source code for more info!
The IPv4
and IPv6
objects provide a way to create and manipulate IP Addresses. They both inherit from IP
.
IP addresses can be created either directly by instantiating IPv4
or IPv6
, or using the convenience factory method IP::create($ip)
.
$ip = new IPv4('192.168.0.1');
$ip = new IPv6('2001:db8::');
$ip = new IPv6('::192.168.0.0'); // IPV4-mapped IPv6
$ip = new IPv6('::ffff:192.168.0.0'); // IPV4-mapped IPv6
$ip = IP::create('192.168.0.1'); // return IPv4
$ip = IP::create('2001:db8::'); // return IPv6
It's also possible to create an IP address object from various types:
- An signed integer (such as the result of
ip2long
), a double containing an signed/unsigned integer value, or an string containing an unsigned integer value. In the factory method, integers less than 2^32 will be considered to be IPv4 by default. - A binary string (such as the result of
inet_pton
). Binary strings must be exactly 4 chars (32 bits) for IPv4 and 16 chars (128 bits) for IPv6. - A GMP ressource number.
$ip = IP::create(294967295); // 17.148.215.255
$ip = IP::create("\000\000\000*"): // 0.0.0.42
A InvalidArgumentException
will be thrown in the value provided cannot be converted into an IP address.
IPv4 and IPv6 objects are convertible to string by default. You can also explicitly generate a string representation with humanReadable($compress)
method. The parameter $compress
(default true
) indicates whether or not to display a short version of the address.
$ip = new IPv4(294967295);
echo $ip; // 17.148.215.255
echo $ip->humanReadable(false); // 017.148.215.255
$ip = new IPv6('2a01:8200::');
echo $ip; // 2a01:8200::
echo $ip->humanReadable(false); // 2a01:8200:0000:0000:0000:0000:0000:0000
Note: IPv4-mapped IPv6 will be displayed as plain IPv6 in uncompressed mode.
$ip = new IPv6('::ffff:192.168.0.0');
echo $ip; // ::ffff:192.168.0.0
echo $ip->humanReadable(false),"\n"; // but 0000:0000:0000:0000:0000:ffff:c0a8:0000
Conversion to integer is done with the numeric()
method. Due the limits of the integer type in PHP, this method will return a numeric string, not an actual integer.
This method accepts an optional parameter $base
. Default is to return in base 10 (decimal).
$ip = new IPv4('127.0.0.0');
echo $ip->numeric(); // '2130706432'
echo $ip->numeric(2); // '1111111000000000000000000000000'
echo $ip->numeric(16); // '7f000000'
$ip = new IPv6('2a01:8200::');
echo $ip->numeric(); // '55835404833073476206743540170770874368'
echo $ip->numeric(2); // '101010000000011000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
echo $ip->numeric(16); // '2a018200000000000000000000000000'
PHP doesn't support overloading of operators, so you have to call the methods directly. All methods accepts any data type that can be converted into a IP address.
$ip = new IPv4('127.0.0.0');
echo $ip->plus(1); // 127.0.0.1
echo $ip->minus(1); // 126.255.255.255
Operators will throw a OutOfBoundException
if you reach the boundaries of the given IP address (for example, trying to add 1
to 255.255.255.255
).
$ip = new IPv4('127.0.0.0');
echo $ip->bit_or('255.255.0.0'); // 255.255.0.0
echo $ip->bit_and('255.255.0.0'); // 127.0.0.0
Name | Description |
---|---|
getVersion() |
Return the IP version (4 or 6) |
isPrivate() |
Return true if the address is allocated for private networks |
isPublic() |
Return true if the address is allocated for public networks |
The IPv4Block
and IPv6Block
objects provide a way to create and manipulate IP networks. They use the CIDR block notation (e.g. 192.168.0.0/24
). They both inherit from IPBlock
.
Like IP addresses, blocks can be created either by instantiating directly IPv4Block
or IPv6Block
, or by using the convenience factory method IPBlock::create()
.
$block = new IPv4Block('128.0.0.0/16');
$block = new IPv4Block('128.0.0.0', '16'); // alternate way of calling the constructor
$block = new IPv6Block('2001:0db8::/32');
$block = new IPv6Block('2001:0db8::', '32'); // alternate way of calling the constructor
$block = IPBlock::create('128.0.0.0/16'); // IPv4Block
- The IP parameter can be anything that can be converted into an IP address (string, integer, etc.)
- The prefix must be an integer between 0 and 32 (IPv4) or 0 and 128 (IPv6)
Name | Description |
---|---|
getFirstIp() |
Return the first IP of the block. (alias getNetworkAddress() ) |
getLastIp() |
Return the last IP of the block. (alias getBroadcastAddress() ) |
getMask() |
Return the net mask (IP object) |
getDelta() |
Return the delta to last IP of the block, aka "host mask" (IP object) |
getNbAddresses() |
Return the number of IP addresses in block. Because this number can be huge, this returns a numeric string, not an actual integer. |
Example:
$block = new IPv4Block('128.0.0.0/16');
echo $block->getMask(); // 255.255.0.0
echo $block->getDelta(); // 0.0.255.255
echo $block->getFirstIp(); // 128.0.0.0
echo $block->getLastIp(); // 128.0.255.255
echo $block->getNbAddresses(); // '65536'
$block = new IPv6Block('2001:0db8::/32');
echo $block->getMask(); // ffff:ffff::
echo $block->getDelta(); // ::ffff:ffff:ffff:ffff:ffff:ffff
echo $block->getFirstIp(); // 2001:db8::
echo $block->getLastIp(); // 2001:db8:ffff:ffff:ffff:ffff:ffff:ffff
echo $block->getNbAddresses(); // '79228162514264337593543950336'
Like IP addresses, you can make addition and subtractions with blocks. You cannot however do bitwise operations.
$block = new IPv4Block('192.168.0.0/24');
echo $block->plus(42); // 192.168.42.0/24
echo $block->minus(42); // 192.167.214.0/24
Operators will throw a OutOfBoundException
if you reach the boundaries of the given IP version (for example, if you try to add 256
to 255.255.255.0/24
).
IP blocks are containers for IP addresses or other IP blocks. You can test whether a block contains another block or IP, or is contained by another block using contains
and isIn
. The method isIn
is also available for IP objects, to test if a given IP is in a given block.
The method overlaps
returns true if the block overlaps another block, whether is is bigger or smaller.
$block = IPBlock::create('192.168.0.0/24');
$block->contains('192.168.0.42'); // true
$block->contains('192.168.1.0/24'); // false
$block->isIn('192.168.0.0/16'); // true
$block->overlaps('192.168.0.0/16'); // true
$ip = IP::create('192.168.0.42');
$ip->isIn($block); // true
IP addresses contained in a block can be iterated with foreach
directly using the block object.
$block = IPBlock::create('192.168.0.0/24');
foreach ( $block as $ip ) {
echo $ip,"\n";
}
// outputs:
// 192.168.0.0
// 192.168.0.1
// 192.168.0.2
// ...
// 192.168.0.255
It's also possible to access an IP address directly using array notation.
$block = IPBlock::create('192.168.0.0/24');
echo $block[0]; // 192.168.0.0
echo $block[42]; // 192.168.0.42
$block = IPBlock::create('2001:db8::/32');
echo $block['79228162514264337543950335']; // 2001:db8:41:8937:4bc6:a7ef:9abd:6fff
Trying to access an offset outside of the block will throw a OutOfBoundsException
.
Note: It's not possible to use array notation to set values inside the block.
Blocks can be split into smaller blocks with the split($prefix)
method. This method returns a IPBlockIterator
object, so you can loop with foreach
. The value of $prefix
must be greater than the current block prefix. For example, you can split a /16 into /24, but not the other way around. Note that $prefix
accepts an optional leading '/', e.g. you can pass "/24" instead of "24" if you find it clearer.
$blocks = IPBlock::create('192.168.0.0/16')->split('/24');
echo $blocks->count(),"\n"; // 256
foreach ( $blocks as $block ) {
echo $block,"\n";
}
// outputs:
// 192.168.0.0/24
// 192.168.1.0/24
// 192.168.2.0/24
// ...
// 192.168.255.0/24