web-dev-qa-db-ja.com

PHPを使用してサーバーの外部IPを取得するにはどうすればよいですか?

$_SERVER['SERVER_ADDR'] "、しかしそれは私のサーバーのLAN IP(例えば192.168.1.100)を返します。外部IPが欲しいです。

20
Leo Jiang

IPアドレスを返すホストを照会するだけです:

$externalContent = file_get_contents('http://checkip.dyndns.com/');
preg_match('/Current IP Address: \[?([:.0-9a-fA-F]+)\]?/', $externalContent, $m);
$externalIp = $m[1];

または、単にIPだけをエコーするサービスを設定し、次のように使用します。

$externalIp = file_get_contents('http://yourdomain.example/ip/');

リモートIPアドレスをエコーするだけで自分でサービスをセットアップするか、誰かに支払いをしてホストします。 not許可なく他人のサーバーを使用してください。以前は、この回答は私のサービスにリンクされていましたが、今では1秒に複数回ヒットしています。

1つ以上の NATs を持つIPネットワークでは、multiple外部IPアドレスを持つ場合があることに注意してください。これにより、そのうちの1つだけが得られます。

また、このソリューションはもちろん、利用可能なリモートホストに依存します。ただし、広く実装されている標準はないため(ISPはなく、一部のホームルーターのみが PnP )を実装しているため、外部IPを取得する他の方法はありません住所。ローカルNATと通信できたとしても、その背後に別のNATがないことを確信できません。

28
phihag

通常のPHPを使用してルーターを使用している場合、ISPによって指定された基礎となるIPアドレスを取得する方法はありません。外部IPを取得する方法は、あなたのためにそれを取得し、あなたにアドレスをエコーバックします。ちょうどそれを行う便利なサービスを見つけました。 http://ipecho.net/

次を使用できます。

$realIP = file_get_contents("http://ipecho.net/plain");
39
Ben

ip6.me のようなサービスから解析できます:

<?php

// Pull contents from ip6.me
$file = file_get_contents('http://ip6.me/');

// Trim IP based on HTML formatting
$pos = strpos( $file, '+3' ) + 3;
$ip = substr( $file, $pos, strlen( $file ) );

// Trim IP based on HTML formatting
$pos = strpos( $ip, '</' );
$ip = substr( $ip, 0, $pos );

// Output the IP address of your box
echo "My IP address is $ip";

// Debug only -- all lines following can be removed
echo "\r\n<br/>\r\n<br/>Full results from ip6.me:\r\n<br/>";
echo $file;
6
Patrick Moore

解決策を追加するのは、他の人が私にはあまり適していないからです。

  • ドメイン名を持つサーバーで実行する必要があります。 gethostbyname()(考えてみれば、これを先験的に知っていれば実際には問題はありません)
  • cLIでは使用できません($_SERVER Webサーバーによって設定されます)
  • 特定の形式のifconfig出力を想定します。これには、複数の非パブリックインターフェイスを含めることができます
  • 誰かのウェブサイトの解析に依存する(誰もが消えたり、URLを変更したり、フォーマットを変更したり、あなたに嘘をつき始めたりするなど、すべて予告なしに)

これは私が提案するものです:

$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
$res = socket_connect($sock, '8.8.8.8', 53);
// You might want error checking code here based on the value of $res
socket_getsockname($sock, $addr);
socket_shutdown($sock);
socket_close($sock);

echo $addr; // Ta-da! The IP address you're connecting from

そこにあるIPアドレスは GoogleパブリックDNS サーバーです。彼らはしばらくの間それを実行していると信じています。ランダム接続の試行をあまり気にしない人(自分自身かもしれません)に属するパブリックIPアドレスである限り、そこでどのアドレスを使用するかは重要ではありません。

これは answer に基づいています。Pythonで同様の問題が発生したときに出くわしました。


追伸:あなたのマシンとインターネットの間で魔術が行われている場合、上記がどの程度うまくいくかわかりません。

5
jeteon

これを試すことができます:

$ip = gethostbyname('www.example.com');
echo $ip;

ドメイン名に関連付けられたIPアドレスを取得します。

4
jakx

私はこの質問が古くて長い間答えられていたことを知っていますが、私は同じことをグーグルで探していて、自分の「ハック」を追加したいと思っています。これを機能させるには、Webリクエストを外部IPアドレスから送信するか、$own_url自身への外部リクエストを行うURLへ。

重要なのは、スクリプトに外部IPアドレスを取得するよりも、スクリプトに自分自身への要求を行わせる場合です。

<?php
if (isset($_GET['ip'])) {
    die($_SERVER['REMOTE_ADDR']);
}
$own_url = (isset($_SERVER['HTTPS']) ? 'https' : 'http') . '://'.$_SERVER['HTTP_Host'].$_SERVER['SCRIPT_NAME'];
$ExternalIP = file_get_contents($own_url.'?ip=1');
echo $ExternalIP;
?>
1
Martin

また、ホスト名またはサーバー名に基づいてDNS Aレコードを介してIPを取得できます。

$dnsARecord = dns_get_record($_SERVER['HTTP_Host'],DNS_A);
if ( $dnsARecord ) echo 'IPv4: '.$dnsARecord[0]['ip'];
$dnsARecord = dns_get_record($_SERVER['HTTP_Host'],DNS_AAAA);
if ( $dnsARecord ) echo 'IPv6: '.$dnsARecord[0]['ip'];

2つのうちの1つが必要なものを提供しない場合、HTTP_Hostの代わりにSERVER_NAMEを使用することもできます。

ただし、これは、サーバーがDNSに対応して正しく構成されていることを前提としています。これは常にそうであるとは限りません。おそらくより良いifconfigを使用して他の答えを参照してください。

0
Arthur

他の回答にはこのことのためのコードがたくさんあると思いますが、私の答えは短いですが、IPを取得するにはシェルでコマンドを実行する必要があります...

しかし、それは短くて速い、と思う...

php execute bash> bash run> bash get ip> php get ip

echo Shell_exec( "Dig +short myip.opendns.com @resolver1.opendns.com");

私の英語で申し訳ありませんが、すべての人に役立つことを願っています...

参照: シェルスクリプトで外部IPアドレスを取得するにはどうすればよいですか?

0
DarckBlezzer

PHPがLinuxサーバーで実行されていると仮定すると、PHPのexec関数を使用してifconfigを呼び出すことができます。

$command = "ifconfig";  /// see notes below
$interface = "eth0";    // 
exec($command, $output);
$output = implode("\n",$output);
if ( preg_match('/'.preg_quote($interface).'(.+?)[\r\n]{2,}/s', $output, $ifaddrsMatch)
        && preg_match_all('/inet(6)? addr\s*\:\s*([a-z0-9\.\:\/]+)/is', $ifaddrsMatch[1], $ipMatches, PREG_SET_ORDER) )
{
    foreach ( $ipMatches as $ipMatch ) 
        echo 'public IPv'.($ipMatch[1]==6?'6':'4').': '.$ipMatch[2].'<br>';
}

時々$ commandとしてifconfigのフルパスを指定しなければならないことに注意してください。これを見つけるには

whereis ifconfig

シェルプロンプトから。さらに、$ interfaceには、WANへのリンクがあるサーバーのメインネットワークインターフェイスの名前を設定する必要があります。

Windowsでは、もちろんifconfig(および対応する調整された正規表現)の代わりにipconfigを使用して、同様のことができます。

0
Arthur

サーバーにドメイン名がある場合は、pingを実行するか、次を使用できます。

$sMyServerIP = gethostbyname('yourdomain.com');
echo $sMyServerIP;

外側のIPアドレスが返されます。

0
Codebeat