2024 年 PHP Conference Japan

inet_pton

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

inet_pton將人類可讀的 IP 位址轉換為其壓縮的 in_addr 表示法

說明

inet_pton(字串 $ip): 字串|false

此函式將人類可讀的 IPv4 或 IPv6 位址(如果 PHP 使用 IPv6 支援編譯)轉換為適當的 32 位元或 128 位元二進制結構。

參數

ip

人類可讀的 IPv4 或 IPv6 位址。

回傳值

回傳給定 ipin_addr 表示法,如果給定的 ip 語法無效(例如,沒有點號的 IPv4 位址或沒有冒號的 IPv6 位址),則回傳 false

範例

範例 #1 inet_pton() 範例

<?php
$in_addr
= inet_pton('127.0.0.1');

$in6_addr = inet_pton('::1');
?>

參見

  • ip2long() - 將包含 (IPv4) 網際網路通訊協定位址的字串轉換為長整數
  • long2ip() - 將長整數位址轉換為 (IPv4) 網際網路標準點分十進位格式的字串
  • inet_ntop() - 將壓縮的網際網路位址轉換為人類可讀的表示法

新增註記

使用者貢獻的註記 6 則註記

18
TuRn3r
10 年前
小心,開頭為 0 的位址會回傳 false。

範例
<?php
inet_pton
('172.27.1.04'); // 回傳 false
inet_pton('172.27.1.4') ;// 回傳正確的結果
?>
10
me at diogoresende dot net
18 年前
如果您想使用上述函式,您應該先測試 ':' 字元,再測試 '.' 字元。意思是,您應該先檢查它是否為 IPv6 位址,再檢查是否為 IPv4 位址。
為什麼? IPv6 允許這種表示法

::127.0.0.1

如果您檢查 '.' 字元,您會認為這是 IPv4 位址,並且它會失敗。
11
francis dot besset at gmail dot com
13 年前
可以透過 AF_INET6 常數來驗證 PHP 是否使用 --disable-ipv6 選項編譯。

<?php

if (defined('AF_INET6')) {
echo
"PHP 編譯時沒有使用 --disable-ipv6 選項";
} else {
echo
"PHP 編譯時使用了 --disable-ipv6 選項";
}

?>
4
admin at hanzlsoft dot eu
3 年前
關於 ::127.0.0.1 表示法

這是一個非常特殊的案例,不需要處理。這種表示法是保留給 IPv4 相容的 IPv6 位址的。
例如,::ffff:192.0.2.128 的表示法可以很容易地讀作「對應到 IPv4 位址 192.0.2.128 的 IPv6 位址」

然而,正如 RFC 所說
https://tools.ietf.org/html/rfc5156#page-2

2.2. IPv4 對應位址

::FFFF:0:0/96 是 IPv4 對應位址 [RFC4291]。這些位址
不應出現在公共網際網路上。

2.3. IPv4 相容位址

::<ipv4-address>/96 是 IPv4 相容位址 [RFC4291]。
這些位址已被棄用,不應出現在公開的
網際網路上。

這表示只有在需要與私人 IP 相容時才需要處理這種表示法。
10
strata_ranger at hotmail dot com
15 年前
如果輸入字串不是可讀的 IP 位址,inet_pton() 會產生 E_WARNING 並返回 FALSE。inet_ntop() 也是如此。

此外,inet_pton() 不識別輸入字串中的網路遮罩表示法(例如:「1.2.3.4/24」或「1:2::3:4/64」)。這與某些資料庫系統(如 PostgreSQL)支援 IP 位址類型的做法不同,因此如果您在 PHP 中處理 IP 位址時需要這種功能,則必須自行撰寫。

一個粗略的例子

<?php

// Sample IP addresses
$ipaddr = '1.2.3.4/24'; // IPv4 with /24 netmask
$ipaddr = '1:2::3:4/64'; // IPv6 with /64 netmask

// Strip out the netmask, if there is one.
$cx = strpos($ipaddr, '/');
if (
$cx)
{
$subnet = (int)(substr($ipaddr, $cx+1));
$ipaddr = substr($ipaddr, 0, $cx);
}
else
$subnet = null; // No netmask present

// Convert address to packed format
$addr = inet_pton($ipaddr);

// Let's display it as hexadecimal format
foreach(str_split($addr) as $char) echo str_pad(dechex(ord($char)), 2, '0', STR_PAD_LEFT);
echo
"<br />\n";

// Convert the netmask
if (is_integer($subnet))
{
// Maximum netmask length = same as packed address
$len = 8*strlen($addr);
if (
$subnet > $len) $subnet = $len;

// Create a hex expression of the subnet mask
$mask = str_repeat('f', $subnet>>2);
switch(
$subnet & 3)
{
case
3: $mask .= 'e'; break;
case
2: $mask .= 'c'; break;
case
1: $mask .= '8'; break;
}
$mask = str_pad($mask, $len>>2, '0');

// Packed representation of netmask
$mask = pack('H*', $mask);
}

// Display the netmask as hexadecimal
foreach(str_split($mask) as $char) echo str_pad(dechex(ord($char)), 2, '0', STR_PAD_LEFT);

?>
2
dave at php dot net
9 年前
如果您收到 IPv6 位址的「無法識別的位址」錯誤,則可能是您的 PHP 版本未編譯 IPv6 支援。

要檢查,請載入 phpinfo(); 並查看「IPv6 支援」是否設定為「已停用」。
To Top