When working on PHP projects, I sometimes need some networking utilities. This repository provides them. You can think about executing a ping request, scanning a network, getting IP information, etcetera.
For those purposes I wrote a library that's been tested on both Windows and Linux servers.
Below you'll find the documentation of the library. Source code can be found at https://bitbucket.org/garrcomm/php-networking-utilities.
When working on PHP projects, I often need some network related methods. This repository contains a list of classes that help with that. This package works on PHP 7.4 and higer, including PHP 8.
These services are currently included:
The Dns Service is a wrapper for nslookup
that gives detailed and structured responses.
The IpTools Service wraps around some IP related commands and also returns structured objects.
There are also a few very useful data models;
The Url Model is an object orientated wrapper around parse_url
with the possibility to also modify URLs.
The Ipv4Address and Ipv4Range Models helps formatting IPv4 addresses and performs some subnet based calculations.
The MacAddress Model helps validating and formatting MAC addresses.
The DnsResult and DnsAnswer Models are returned by the Dns
service.
All data models can be serialized with json_encode
and var_export
.
Also, they can all be represented as a string.
You can install these utilities with Composer by running composer require garrcomm/networking-utilities
or by copying the source files from the src folder.
Code quality is checked with several tools to make sure everything is working properly and well documented. The following methods are in use:
These utilities should work on most Windows and Linux installations.
For Linux, it can be possible that you'll need to install some additional packages (depending on the OS config we'll need the commands nslookup
, ip
, ipconfig
, ifconfig
, ping
and/or arp
).
Whenever one of those commands is missing, a RuntimeException
with code 127
will be thrown.
On most Linux distros these tools are already included though. Otherwise, it's easy to solve by locating the appropriate package (apt-file search --regexp 'bin/ping$'
or yum provides ping
, depending on your distro).
If you've installed Docker, you can execute these commands in the root of the project:
docker compose up -d
docker compose exec php bash
This will put you in a terminal with the same configuration as the pipelines used for automated testing of this code. In this terminal, you've got a few commands:
# Download all (development) dependencies
composer install
# Run code sniffer
vendor/bin/phpcs
# Run static analyser
vendor/bin/phpstan
# Run unit tests
vendor/bin/phpunit
In this container, the command line tools used in this package are also installed.
Below are all available classes in this package. They're divided into two categories;
The Dns service wraps around nslookup
and returns neat DNS lookup results.
It's also possible to change the target nameserver.
$dns = new \Garrcomm\Netutils\Service\Dns();
$dns->setDnsServer('dns.google');
var_dump($dns->getMx('google.com'));
class Dns {
/* Constants */
public const A = 'internet address';
public const AAAA = 'AAAA address';
public const CNAME = 'canonical name';
public const MX = 'mail exchanger';
public const NS = 'nameserver';
public const TXT = 'text';
/* Methods */
public __construct(string dnsServer = 'dns.google')
public getA(string domain): DnsResult
public getAAAA(string domain): DnsResult
public getCname(string domain): DnsResult
public getDnsServer(): string
public getMx(string domain): DnsResult
public getNs(string domain): DnsResult
public getTxt(string domain): DnsResult
public setDnsServer(string dnsServer): void
}
Dns::A
An IPv4 internet address (A record)
Dns::AAAA
An IPv6 internet address (AAAA record)
Dns::CNAME
An alias to another DNS record (CNAME record)
Dns::MX
IP address(es) to an email server (MX record)
Dns::NS
DNS names of all responsible nameservers (NS record)
Dns::TXT
A record containing plain text, used for domain verification, SPF, DKIM, etc. (TXT record)
IpTools helps with basic IPv4 related stuff;
$tools = new \Garrcomm\Netutils\Service\IpTools();
// getLocalIpv4s() returns a list of all IPv4 addresses on the current machine
$ips = $tools->getLocalIpv4s();
foreach ($ips as $networkName => $ip) {
echo 'Network ' . $networkName . ' has IP address ' . $ip->getIpAddress() . PHP_EOL;
}
// networkQuickScan returns a list of all IPv4 addresses that can be found within a network
$ip = new \Garrcomm\Netutils\Model\Ipv4Address('192.168.2.1', '255.255.255.0');
$ips = $tools->networkQuickScan($ip);
foreach ($ips as $mac => $ip) {
echo 'System ' . $mac . ' has IP address ' . $ip->getIpAddress() . PHP_EOL;
}
// With getIpByMac you can get the IP based on a MAC address
$mac = new \Garrcomm\Netutils\Model\MacAddress('aa-bb-cc-dd-ee-ff');
$ip = $tools->getIpByMac($mac);
echo 'Mac address ' . $mac . ' resolves to ' . $ip . PHP_EOL;
// With isLocalIp you can look up if an IP address is a local IP address
$ips = ['192.168.0.1', '8.8.8.8', '10.0.0.1'];
foreach ($ips as $ip) {
echo $ip . ' is ' . ($tools->isLocalIp($ip) ? 'a' : 'not a') . ' local IP' . PHP_EOL;
}
class IpTools {
/* Methods */
public __construct(string operatingSystem = 'Linux')
public getIpByMac(MacAddress macAddress, ?Ipv4Address networkInterface = null): Ipv4Address
public getLocalIpv4s(): array<string,Ipv4Address>
public getMacByIp(Ipv4Address ipv4Address): MacAddress
public isLocalIp(?integer|string|Ipv4Address ipAddress): bool
public networkQuickScan(Ipv4Address networkInterface): array<string,Ipv4Address>
}
IpTools::__construct — Initializes IP tools
IpTools::getIpByMac — Looks up the matching IP address for a MAC address.
IpTools::getLocalIpv4s — Returns a list of all local IPv4 addresses
IpTools::getMacByIp — Returns the known MAC address by its IP address.
IpTools::isLocalIp — Returns true when the IP is a local IP
The IANA has defined these IP addresses as private or local:
10.0.0.0 to 10.255.255.255, a range that provides up to 16 million unique IP addresses.
172.16.0.0 to 172.31.255.255, providing about 1 million unique IP addresses.
192.168.0.0 to 192.168.255.255, which offers about 65,000 unique IP addresses.
IpTools::networkQuickScan — Returns a list of all known IP addresses in a network
This class wraps and enhances the PHP method parse_url
so you can read and modify URLs
// You can initiate the URL class in two ways;
// 1. By using the current request
$url = \Garrcomm\Netutils\Model\Url::current();
// 2. By using a URL in the constructor
$url = new \Garrcomm\Netutils\Model\Url('https://localhost/foo?one=two&bar=baz');
// It's possible to set and remove elements, in one chain.
echo $url
->setHostname('foo.bar')
->setPath('baz')
->setQuery('bar', 'foo')
->removeQuery('one')
->setFragment('fragment-here'); // https://foo.bar/baz?bar=foo#fragment-here
// The object can be treated as a string:
echo '<a href="' .htmlspecialchars($url) . '">Click here</a>';
// The object can also be json serialized:
echo json_encode($url);
class Url implements JsonSerializable {
/* Methods */
public __construct(string url)
public getFragment(): string
public getFullQuery(): array<int|string,mixed>
public getHostname(): string
public getPassword(): string
public getPath(): string
public getPort(): int
public getQuery(string key): mixed|string
public getScheme(): string
public getUsername(): string
public jsonSerialize(): mixed
public removeFragment(): self
public removeFullQuery(): self
public removePassword(): self
public removePort(): self
public removeQuery(string key): self
public removeUsername(): self
public setFragment(string fragment): self
public setFullQuery(array<string,mixed> query): self
public setHostname(string hostname): self
public setPassword(string password): self
public setPath(string path): self
public setPort(integer port): self
public setQuery(string key, string|mixed value): self
public setUsername(string username): self
public __toString(): string
public static current(): self
public static __set_state(mixed[] state): self
}
var_export()
.The Ipv4Address
model is also used in the IpTools
service, but it can also help with different notations
and even calculate complete subnets;
$ip = new \Garrcomm\Netutils\Model\Ipv4Address('192.168.1.1', '255.255.255.0');
echo 'CIDR notation: ' . $ip->getCidrAddress() . PHP_EOL;
echo 'Broadcast address: ' . $ip->getBroadcastAddress() . PHP_EOL;
echo 'Network address: ' . $ip->getNetworkAddress() . PHP_EOL;
echo 'Amount of IP\'s in range: ' . count($ip->getIpRange()) . PHP_EOL;
class Ipv4Address implements JsonSerializable {
/* Methods */
public __construct(?string|integer ipAddress = null, ?string|integer subnetAddress = null)
public getBitMask(): int
public getBroadcastAddress(): string
public getCidrAddress(): string
public getIpAddress(): string
public getIpRange(): Ipv4Address[]|Ipv4Range
public getNetworkAddress(): string
public getSubnetAddress(): string
public jsonSerialize(): mixed
public setBitMask(integer bitMask): Ipv4Address
public setCidrAddress(string ipMask): Ipv4Address
public setIpAddress(?string|integer ipAddress): Ipv4Address
public setSubnetAddress(?string|integer subnetAddress): Ipv4Address
public __toString(): string
public static __set_state(mixed[] state): self
}
Ipv4Address::__construct — Creates a new IP entity
Input can be an IP address as integer, regular, or in CIDR format.
Ipv4Address::getBitMask — Returns the bitmask presentation of the subnet
Ipv4Address::getBroadcastAddress — Returns the broadcast address
Ipv4Address::getCidrAddress — Returns the IP address in CIDR notation
Ipv4Address::getIpAddress — Returns the IP address
Ipv4Address::getIpRange — Returns the full IP range in this network
Ipv4Address::getNetworkAddress — Returns the network address
Ipv4Address::getSubnetAddress — Returns the subnet address
Ipv4Address::jsonSerialize — JsonSerializable::jsonSerialize — Specify data which should be serialized to JSON
Ipv4Address::setBitMask — Sets the bitmask presentation of the subnet
Ipv4Address::setCidrAddress — Fills this entity with an IP address based on CIDR notation
Ipv4Address::setIpAddress — Sets the IP address
Ipv4Address::setSubnetAddress — Sets the subnet address
Ipv4Address::__toString — Gets a string representation of the object
Ipv4Address::__set_state — This static method is called for classes exported by var_export()
.
You can use this object as an array:
// Defines a range
$range = new \Garrcomm\Netutils\Model\Ipv4Range('192.168.2.0', 24);
// Uses the Countable interface to return the amount of IPs in range
echo 'Amount of IPs in the range: ' . count($range) . PHP_EOL;
// Uses the Iterator interface to walk through the results
foreach ($range as $ip) {
echo '- ' . $ip . PHP_EOL;
}
// Uses the ArrayAccess interface to walk through the results
for ($i = 0; $i < count($range); ++$i) {
echo '- ' . $range[$i] . PHP_EOL;
}
// Returns a json array with all IPs in range
echo json_encode($range, JSON_PRETTY_PRINT);
// Returns the IP range as string
echo $range . PHP_EOL;
class Ipv4Range implements Iterator, Countable, ArrayAccess, JsonSerializable, Traversable {
/* Methods */
public __construct(string|integer networkAddress, integer bitMask)
public count(): int
public current(): mixed
public jsonSerialize(): mixed
public key(): mixed
public next(): void
public offsetExists(mixed offset): bool
public offsetGet(mixed offset): mixed
public offsetSet(mixed offset, mixed value): void
public offsetUnset(mixed offset): void
public rewind(): void
public valid(): bool
public __toString(): string
public static __set_state(mixed[] state): self
}
var_export()
.class MacAddress implements JsonSerializable {
/* Constants */
public const LOWERCASE = 0;
public const UPPERCASE = 1;
/* Methods */
public __construct(string macAddress)
public format(string separator = ':', integer casing = 0): string
public jsonSerialize(): mixed
public set(string macAddress): MacAddress
public __toString(): string
public static __set_state(mixed[] state): self
}
MacAddress::LOWERCASE
MacAddress::UPPERCASE
var_export()
.class DnsResult implements JsonSerializable {
/* Methods */
public __construct(string question, DnsAnswer[] answers, string dnsHostname, string dnsAddress)
public getAnswers(boolean sorted = false): DnsAnswer[]
public getDnsAddress(): string
public getDnsHostname(): string
public getQuestion(): string
public jsonSerialize(): mixed
public __toString(): string
public static __set_state(mixed[] state): self
}
var_export()
.class DnsAnswer implements JsonSerializable {
/* Methods */
public __construct(string type, string result, integer ttl, ?integer priority)
public getPriority(): int
public getResult(): string
public getTtl(): int
public getType(): string
public jsonSerialize(): mixed
public __toString(): string
public static __set_state(mixed[] state): self
}
var_export()
.