PHP inet_ntop() Function: Everything You Need to Know
As a PHP developer, you may need to convert a binary string containing an IPv4 or IPv6 address to a human-readable format. The inet_ntop() function is a
The inet_ntop() function converts a packed binary IP address into a human-readable string. The name stands for "network to presentation": it takes the compact, fixed-length form an IP address has in memory (or in a database column) and turns it back into the dotted-decimal (127.0.0.1) or colon-hexadecimal (::1) notation you can read and log.
This page explains what the packed format is, how to use inet_ntop() for both IPv4 and IPv6, how it pairs with inet_pton(), how to handle errors, and when reaching for it is the right call.
Why a "packed" format exists
An IPv4 address such as 192.168.1.1 is really just 32 bits — four bytes. An IPv6 address is 128 bits — sixteen bytes. The readable text you normally see is a presentation of those bytes, not the bytes themselves.
When you store or compare addresses at scale, the raw bytes are smaller and faster: a VARBINARY(16) column holds any IPv4 or IPv6 address, sorts correctly, and indexes well. inet_pton() produces that packed form; inet_ntop() reverses it so humans can read it again.
"127.0.0.1" --inet_pton()--> \x7f\x00\x00\x01 (4 packed bytes)
\x7f\x00\x00\x01 --inet_ntop()--> "127.0.0.1" (readable text)Syntax
inet_ntop(string $ip): string|falseThe function takes a single parameter:
$ip— a binary string holding the packed in-address. It must be exactly 4 bytes for IPv4 or 16 bytes for IPv6.
It returns the address as a readable string, or false if the input is not a valid 4- or 16-byte packed address.
Converting an IPv4 address
A packed IPv4 address is four raw bytes, one per octet. The loopback address 127.0.0.1 is therefore \x7f (127), \x00, \x00, \x01:
Hand-writing escape sequences is error-prone. In practice you obtain the packed bytes from inet_pton() or from a database, then pass them straight to inet_ntop():
<?php
$packed = inet_pton("192.168.1.1"); // text -> 4 packed bytes
echo inet_ntop($packed); // Outputs: 192.168.1.1Converting an IPv6 address
The same function handles IPv6 — pass it a 16-byte packed string and it returns the compressed colon-hexadecimal form, collapsing runs of zeros to :: automatically:
<?php
$packed = inet_pton("2001:db8::1");
echo inet_ntop($packed); // Outputs: 2001:db8::1Because one function covers both families, you can round-trip any address without branching on its type — handy when a column may contain either kind.
Handling invalid input
If the binary string is not exactly 4 or 16 bytes, inet_ntop() returns false and emits a warning. Always check the result before using it:
<?php
$result = inet_ntop("not a packed address");
if ($result === false) {
echo "Invalid packed address.";
} else {
echo $result;
}
// Outputs: Invalid packed address.Use a strict === false comparison: a loose check would also reject "0.0.0.0", which is a valid address.
inet_ntop() vs. ip2long()
For IPv4 you may also see long2ip(), which turns a 32-bit integer back into a dotted string. The difference:
ip2long()/long2ip()work with an integer representation and are IPv4-only.inet_pton()/inet_ntop()work with a binary string and support both IPv4 and IPv6.
If your application has to handle IPv6 at all, prefer the inet_* pair so a single code path serves every address.
When to use it
- Reading addresses back from storage — a
VARBINARY(16)column stores any address compactly;inet_ntop()renders rows for display or logging. - Normalizing user input — round-tripping through
inet_pton()theninet_ntop()yields a canonical form (for example2001:0db8::0001becomes2001:db8::1), so equal addresses compare as equal strings. - Working with raw socket data — packed addresses returned by low-level network calls become readable for logs and error messages.
Related functions
inet_pton()— the inverse: readable address to packed binary string.ip2long()— IPv4 string to integer.long2ip()— integer back to an IPv4 string.gethostbyname()— resolve a hostname to its IPv4 address.
Conclusion
inet_ntop() turns a packed 4- or 16-byte IP address back into readable text for both IPv4 and IPv6, complementing inet_pton(). Store addresses in their compact binary form for efficient indexing, convert them with inet_ntop() when you need to show or log them, and always check for a false return on malformed input.