PHPでIPv6かIPv4を表示する

PHPIPv6IPv4を表示する

PHPで、IPv6でアクセスされているか、IPv4でアクセスされているかを表示する方法。
インターネット上で紹介されている方法を3つまとめました。

  1. VirtualHostで分ける
  2. サーバーアドレス $_SERVER['SERVER_ADDR'] で分ける
  3. リモートアドレス $_SERVER['REMOTE_ADDR'] で分ける

1. VirtualHostで分ける

にぽたん研究所にも紹介されている、VirtualHostでIPv6IPv4のサーバーアドレスを分けてリクエストヘッダーに値をセットする方法です。3つの中で一番スマートな感じがします。

  1. httpd.conf
  2. <VirtualHost 192.168.AAA.BBB:80>
  3.     RequestHeader set X-IP-Version 4
  4. </VirtualHost>
  5. <VirtualHost [2001:e41:AAAA:BBBB::1]:80> ※ [ ] を忘れずに!
  6.     RequestHeader set X-IP-Version 6
  7. </VirtualHost>
  8.  

 

  1. ipv6ipv4.php
  2. $ip_family = htmlspecialchars(@$_SERVER["HTTP_X_IP_VERSION"],ENT_QUOTES,'UTF-8');
  3. if( $ip_family == 6 ) {
  4.     $ipkind = 'ipv6';
  5. } elseif( $ip_family == 4 ) {
  6.     $ipkind = 'ipv4';
  7. }
  8.  

 

2. サーバーアドレス $_SERVER['SERVER_ADDR'] で分ける

サーバーアドレスを$_SERVER['SERVER_ADDR']で取得して、IPv6のサーバーアドレスに一致すればIPv6IPv4のサーバーアドレスに一致すればIPv4と表示します。$_SERVER['SERVER_ADDR']は2通り、もしくはそれ以上ある場合でもホワイトリストで判別できるはずなのでこれで十分ではないかと思いました。

  1. ipv6ipv4.php
  2. if ($_SERVER['SERVER_ADDR'] == '2001:e41:AAAA:BBBB::1') {
  3.     $ipkind = 'ipv6';
  4. } elseif($_SERVER['SERVER_ADDR'] == '192.168.AAA.BBB'){
  5.     $ipkind = 'ipv4';
  6. }
  7.  

 

3. リモートアドレス $_SERVER['REMOTE_ADDR'] で分ける

リモートアドレスを$_SERVER['REMOTE_ADDR']で取得して、コロンが含まれていればIPv6、ドットが含まれていればIPv4と表示します。リモートアドレスで判別するサンプルでは、正規表現IPv6アドレスの形式に一致しているかで判別するサンプルをいくつか見ましたが、コロンかドットの条件分けで十分ではないかと思いました。

  1. ipv6ipv4.php
  2. $count_semi = substr_count($_SERVER['REMOTE_ADDR'], ':');
  3. $count_dot = substr_count($_SERVER['REMOTE_ADDR'], '.');
  4. if ($count_semi > 0 && $count_dot == 0) {
  5.     $ipkind = 'ipv6';
  6. } elseif($count_semi == 0 && $count_dot > 0){
  7.     $ipkind = 'ipv4';
  8. }
  9.  

 

おわり

 

参照サイト

 

関連記事