PHPでは、 gethostbyname関数は、ホスト名をIPv4アドレスに解決するために使用される一般的な方法です。その典型的な使用法は非常に単純です:
<?php
$ip = gethostbyname("example.com");
echo $ip;
?>
ただし、ネットワーク環境がIPv6に徐々に移行すると、多くの開発者が心配します。GethostbynameはIPv6環境に互換性がありますか? IPv6アドレスの解析をサポートしていますか?潜在的な問題はありますか?それを解決する方法は?
Gethostbyname関数は、従来のIPv4設計に基づいています。その主な機能は、ホスト名に対応する最初のIPv4アドレス文字列を返すことです。クエリホストにIPv4アドレスがなく、IPv6アドレスのみが存在する場合、 gethostbynameは正常に有効なIPを返すことはできません。
簡単に言えば:
IPv4アドレス解像度のみがサポートされています。
IPv6アドレスはサポートされていません。
ホスト名がIPv6アドレスにのみ解析されている場合、通常、返品結果はホスト名自体です(正常に解析されていないことを示します)。
サンプルコード:
<?php
$ip = gethostbyname("ipv6only.example.com");
echo $ip; // 可能な出力“ipv6only.example.com”,その代わり IP 住所
?>
これは、純粋なIPv6環境では、 Gethostbynameの適用性が限られていることを示しています。
IPv6アドレスを取得できません
gethostbynameはIPv4アドレスのみを返し、AAAAレコード、つまりIPv6アドレスを処理できません。
互換性が不十分である<br> 最新のネットワークでは、ますます多くのサーバーがIPv6アドレスのみを使用し、 Gethostbynameはニーズを満たすことができません。
潜在的なエラー<br> プログラムが有効なIPを取得するためにgethostbynameに依存している場合、純粋なIPv6ホストに遭遇したときにエラーまたは論理的な例外を引き起こす可能性があります。
IPv6と互換性があるため、PHP 7+が提供するDNS_GET_RECORDやgetAddrinfo関数など、より最新の関数を使用することをお勧めし、 Stream_Socket_ClientでIPv6もサポートできます。
<?php
$hostname = "example.com";
// すべてを取得します A そして AAAA 記録
$records = dns_get_record($hostname, DNS_A + DNS_AAAA);
$ipv4s = [];
$ipv6s = [];
foreach ($records as $record) {
if ($record['type'] === 'A') {
$ipv4s[] = $record['ip'];
} elseif ($record['type'] === 'AAAA') {
$ipv6s[] = $record['ipv6'];
}
}
echo "IPv4 addresses:\n";
print_r($ipv4s);
echo "IPv6 addresses:\n";
print_r($ipv6s);
?>
この方法では、一度にホスト名に対応するすべてのIPv4およびIPv6アドレスを取得できます。
PHP 7.0は後にSocket_GetadDrinfoをSockets Extensionに導入しました。これにより、より完全なアドレス情報を返すことができ、IPv4とIPv6をサポートできます。
<?php
$hostname = "example.com";
$results = socket_getaddrinfo($hostname, null);
foreach ($results as $result) {
$ip = $result['address'];
echo "IP: $ip\n";
}
?>
この方法は、ソケット拡張機能のインストールに依存し、IPv6アドレスをサポートします。
実際のネットワークプログラムでは、 Stream_Socket_Clientを使用して接続を試して、IPv4とIPv6をサポートすることもできます。
<?php
$hostname = "example.com";
$port = 80;
$errno = 0;
$errstr = "";
$fp = @stream_socket_client("tcp://$hostname:$port", $errno, $errstr, 5);
if ($fp) {
$meta = stream_socket_get_name($fp, false);
echo "Connected via IP: $meta\n";
fclose($fp);
} else {
echo "Failed to connect: $errstr ($errno)\n";
}
?>
このメソッドは、基礎となるネットワークスタックを介して適切なIP(IPv4またはIPv6)を自動的に選択します。
GethostbynameはIPv4アドレスのみを解析でき、IPv6をサポートできません。それは徐々に時代遅れの方法と見なされてきました。
IPv6環境では、 gethostbynameが解析を失敗させるか、誤った結果を返す可能性があります。
IPv4およびIPv6アドレスを取得するには、 DNS_GET_RECORDやSocket_GetAdDrinfoなどの最新の方法を使用することをお勧めします。
ネットワーク接続の場合、IPv6をサポートする関数とインターフェイスを使用して、コードが将来のネットワーク環境と互換性があることを確認することをお勧めします。