The
::factory()static method is now deprecated. See the strict-parsing named constructors below.
IP addresses get automatically validated on creation through the static named
constructors; if the IP address supplied is invalid an
InvalidIpAddressException will be thrown.
<?php
use Darsyn\IP\Version\IPv4;
use Darsyn\IP\Exception;
try {
$ip = IPv4::fromProtocol('127.0.0.1');
} catch (Exception\InvalidIpAddressException $e) {
echo 'The IP address supplied is invalid!';
}This library can work with version 4 addresses, version 6 addresses, or both
formats interchangeably using the classes Darsyn\IP\Version\IPv4,
Darsyn\IP\Version\IPv6 and Darsyn\IP\Version\Multi respectively.
All versions implement Darsyn\IP\IpInterface, along with extra interfaces for
each version:
IPv4implementsDarsyn\IP\Version\Version4Interface,IPv6implementsDarsyn\IP\Version\Version6Interface,MultiimplementsDarsyn\IP\Version\MultiVersionInterface(which in turn implements bothVersion4InterfaceandVersion6Interface).
If you try to use a version 6 address with the IPv4 class, or a version 4
address with the IPv6 class, then a Darsyn\IP\Exception\WrongVersionException
will be thrown.
<?php
use Darsyn\IP\Version\IPv4;
use Darsyn\IP\Exception;
try {
$ip = IPv4::fromProtocol('::1');
} catch (Exception\WrongVersionException $e) {
echo 'Only version 4 IP addresses are allowed!';
} catch (Exception\InvalidIpAddressException $e) {
echo 'The IP address supplied is invalid!';
}Note: The
WrongVersionExceptionis provided to give finer control on handling errors. It extendsInvalidIpAddressExceptionso catching it isn't necessary.
Each class has methods for determining the version:
$ip->getVersion()returns the IP address version (eitherint(4)orint(6)).$ip->isVersion($version)returns a boolean value on whether the$ipobject is the version specified in$version(which must be eitherint(4)orint(6)).$ip->isVersion4()returns a boolean value on whether the$ipobject contains a version 4 address.$ip->isVersion6()returns a boolean value on whether the$ipobject contains a version 6 address.
Note: When using the
Multiclass, the address version is determined by what embedding strategy is used rather than what notation was passed to the constructor.
Many instances are constructed for all helper and type methods. Validating the input every time a new instance is constructed slows things down considerably, so to speed up internal processes the constructor does not perform any input validation. Because of this the constructor method has been kept private.
<?php
use Darsyn\IP\Version\Multi as IP;
try {
$ip = new IP('127.0.0.1');
} catch (\Error) {
echo 'Cannot create IP using "new"; please use IP::fromProtocol() instead.';
}Deprecated:
factory()is deprecated because it accepts raw binary sequences as well as protocol notation. Prefer the strict named constructors:fromProtocol()for protocol notation, orfromBinary()for a raw binary sequence.
Darsyn\IP\Contracts\FactoryInterface provides strict, single-purpose entry points:
fromProtocol()parses protocol notation only; a raw binary sequence is rejected with anInvalidIpAddressException.fromBinary()accepts a raw binary sequence only, of exactly the right length, throwing anInvalidBinaryExceptionotherwise.fromHex()accepts a hexadecimal string (no0xprefix, case-insensitive).fromInteger()accepts an IPv4 address as its integer value, between0and4294967295. It is only available on theIPv4andMulticlasses (version 6 addresses do not fit within PHP's native integer type).fromIntegerString()accepts the whole-address value as a base-10 string at any precision: four bytes' worth forIPv4, sixteen forIPv6andMulti.
<?php
use Darsyn\IP\Version\IPv4;
use Darsyn\IP\Exception;
IPv4::factory('abcd'); // Accepted: the raw bytes become "97.98.99.100".
try {
IPv4::fromProtocol('abcd');
} catch (Exception\InvalidIpAddressException $e) {
echo 'Not valid IP notation, and never treated as raw bytes.';
}
IPv4::fromBinary("\x7f\x00\x00\x01"); // string("127.0.0.1")
IPv4::fromHex('7f000001'); // string("127.0.0.1")
IPv4::fromInteger(2130706433); // string("127.0.0.1")
IPv4::fromIntegerString('2130706433'); // string("127.0.0.1")Each strict constructor has a non-throwing companion tryFrom* that returns
null on failure, mirroring the behaviour of PHP enums.
<?php
use Darsyn\IP\Version\IPv4;
if (null === $ip = IPv4::tryFromProtocol($_GET['ip'])) {
echo 'Please supply a valid IPv4 address.';
}Additionally, FactoryInterface::isValid() is available for a simple boolean
check on protocol notation:
<?php
use Darsyn\IP\Version\IPv4;
IPv4::isValid('127.0.0.1'); // bool(true)
IPv4::isValid('abcd'); // bool(false)When using the Multi class, each of these methods accepts an optional
embedding strategy as its final argument.
Note:
InvalidBinaryExceptionextendsInvalidIpAddressException, so existingcatchblocks keep working unchanged.
Once an IP object has been initialised, the IP address value can be returned in either human-readable format or in binary.
This binary string will always be 4 bytes long when using IPv4 and 16 bytes
long when using IPv6 and Multi.
Human-readable format comes in 3 flavours:
- Dot notation is for IPv4 addresses, eg
127.0.0.1. - Compacted is for IPv6 addresses, eg
2001:db8::a60:8a2e:370:7334. - Expanded is for IPv6 addresses, eg
2001:0db8:0000:0000:0a60:8a2e:0370:7334.
toDotAddress() is only available for IPv4 and Multi classes. Calling
toDotAddress() on an instance of Multi that contains a version 6 address
will result in a WrongVersionException being thrown.
<?php
use Darsyn\IP\Version\Multi as IP;
use Darsyn\IP\Exception;
$ip = IP::fromProtocol('127.0.0.1');
try {
echo $ip->toDotAddress(); // string("127.0.0.1")
} catch (Exception\WrongVersionException $e) {
echo 'Cannot convert a version 6 address to dot-notation!';
}toCompactedAddress() is only available for IPv6 and Multi classes.
Calling toCompactedAddress() on an instance of Multi that contains a
version 4 address will result in the IP address being converted to a version 6
address according to the embedding strategy.
<?php
use Darsyn\IP\Version\Multi as IP;
$ip = IP::fromProtocol('127.0.0.1');
echo $ip->toCompactedAddress(); // string("::ffff:7f00:1")toExpandedAddress() is only available for IPv6 and Multi classes. Calling
toExpandedAddress() on an instance of Multi that contains a version 4
address will result in the IP address being converted to a version 6 address
according to the embedding strategy.
<?php
use Darsyn\IP\Version\Multi as IP;
$ip = IP::fromProtocol('127.0.0.1');
$ip->toExpandedAddress(); // string("0000:0000:0000:0000:0000:ffff:7f00:0001")toProtocolAppropriateAddress() is only available for the Multi class. If
the instance of Multi contains a version 4 address, it will be returned in
dot notation, otherwise it returns a compacted version 6 address.
<?php
use Darsyn\IP\Version\Multi as IP;
$ip = IP::fromProtocol('::ffff:7f00:1');
$ip->toProtocolAppropriateAddress(); // string("127.0.0.1")getBinary() returns the 16 byte (4 bytes if using IPv4) binary string of the
IP address. This will most likely contain non-printable characters, so is not
appropriate for displaying.
<?php
use Darsyn\IP\Version\IPv4 as IP;
// The IPv4 address "80.111.111.112" just so happens to be, when converted to
// binary, the same as the binary for the ASCII string "Poop". Today you learnt
// something new.
$ip = IP::fromProtocol('80.111.111.112');
$ip->getBinary(); // string("Poop")getOctets() returns the individual bytes of the binary string as an array of
integers between 0 and 255 (four entries for an IPv4 address, sixteen for
IPv6). Calling it on an instance of Multi that contains a version 4 address
returns the four octets of the embedded IPv4 address.
<?php
use Darsyn\IP\Version\IPv4 as IP;
$ip = IP::fromProtocol('127.0.0.1');
$ip->getOctets(); // array(127, 0, 0, 1)getSegments() returns the eight 16-bit segments (hextets) of an IPv6 address
as an array of integers between 0 and 65535. It is only available for the
IPv6 and Multi classes; calling it on an instance of Multi that contains a
version 4 address will result in a WrongVersionException being thrown.
<?php
use Darsyn\IP\Version\IPv6 as IP;
$ip = IP::fromProtocol('2001:db8::1');
$ip->getSegments(); // array(8193, 3512, 0, 0, 0, 0, 0, 1)toInteger() returns the unsigned 32-bit integer value of an IPv4 address,
between 0 and 4294967295. It is only available for the IPv4 and Multi
classes; calling it on an instance of Multi that contains a version 6 address
will result in a WrongVersionException being thrown. The value can be
re-parsed via fromInteger().
<?php
use Darsyn\IP\Version\IPv4 as IP;
$ip = IP::fromProtocol('127.0.0.1');
$ip->toInteger(); // int(2130706433)toIntegerString() returns the whole-address value in base-10 as a string, at
any precision. It always reflects the full binary width of the address — four
bytes for IPv4, sixteen for IPv6 and Multi, including instances of
Multi that contain an embedded version 4 address (use toInteger() for the
embedded value). The value can be re-parsed via fromIntegerString().
<?php
use Darsyn\IP\Version\IPv6 as IP;
$ip = IP::fromProtocol('::ffff:7f00:1');
$ip->toIntegerString(); // string("281472812449793")toHexString() returns the address as a fixed-width, lowercase hexadecimal
string: eight characters for IPv4, thirty-two for IPv6 and Multi
(regardless of embedded state). The fixed width makes it suitable for sortable,
indexable database columns, and it can be re-parsed via fromHex().
<?php
use Darsyn\IP\Version\IPv4 as IP;
$ip = IP::fromProtocol('127.0.0.1');
$ip->toHexString(); // string("7f000001")The canonical method for casting to a string is toString().
\Stringable is a PHP 8 feature and not available on all supported PHP versions,
so __toString() is implemented independently (deferring to toString()). The
returned string is in protocol-appropriate notation and can be re-parsed via
fromProtocol().
- String casting the
IPv4class is the equivalent of$ip->toDotAddress(). - String casting the
IPv6class is the equivalent of$ip->toCompactedAddress(). - String casting the
Multiclass is the equivalent of$ip->toProtocolAppropriateAddress().
<?php
use Darsyn\IP\Version\Multi as IP;
$ip = IP::fromProtocol('::ffff:7f00:1');
$printableString = (string) $ip; // string("127.0.0.1")All IP classes implement \JsonSerializable (via Contracts\OutputInterface),
so they can be passed directly to json_encode(). The serialised value is the
canonical toString() notation, which can be re-parsed via fromProtocol().
<?php
use Darsyn\IP\Version\Multi as IP;
$ip = IP::fromProtocol('::ffff:7f00:1');
echo \json_encode(['client_ip' => $ip]); // string('{"client_ip":"127.0.0.1"}')