如何使用PHP获取服务器的外部IP?

时间:2011-10-26 21:50:19

标签: php ip

我经常听到有人说使用“$_SERVER['SERVER_ADDR']”,但会返回我服务器的LAN IP(例如192.168.1.100)。我想要外部IP。

12 个答案:

答案 0 :(得分:37)

如果您使用的是路由器,则无法通过传统的PHP获取ISP指定的基础IP地址。获取外部IP的一种方法是找到一个可以为您获取的服务,并将地址回显给您。我发现了一个方便的服务。 http://ipecho.net/

您可以使用:

if (selectedLetters.length() == answer.length) {
    if(selectedLetters.equals(answer)) {
        // Correct answer
    } else {
        // Incorrect answer
    }
}

答案 1 :(得分:28)

只需查询返回您的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地址,或者付某人托管,即可自行设置服务。 未经许可使用其他人的服务器。以前,这个答案与我的服务有关,现在每秒都会被多次击中。

请注意,在具有一个或多个NATs的IP网络中,您可能拥有多个外部IP地址。这只会给你一个。

此外,此解决方案当然取决于可用的远程主机。但是,由于没有广泛实施的标准(没有ISP,只有一些家庭路由器实现UPnP),没有其他方式来获取外部IP地址。即使您可以与本地NAT通信,也无法确定其背后是否存在其他NAT。

答案 2 :(得分:6)

您可以通过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;

答案 3 :(得分:5)

我要添加一个解决方案,因为其他人对我来说并不合适,因为他们:

  • 需要在具有域名的服务器上运行,例如gethostbyname()(如果您考虑一下,如果您事先知道这个问题,那么您实际上并没有问题)
  • 无法在CLI上使用(依赖于$_SERVER中由Web服务器设置的内容)
  • 假设ifconfig输出的特定格式,可包括多个非公共接口
  • 依赖于解析某人的网站(可能会消失,更改网址,更改格式,开始骗你等等,所有这些都不另行通知)

这就是我的建议:

$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 public DNS服务器。我相信他们会在一段时间内运行它。只要它的公共IP地址属于不太注意随机连接尝试的人(你自己可能?),那么你在那里使用的地址真的不重要。

这是基于我在Python遇到类似问题时遇到的answer

P.S。:我不确定如果您的机器和互联网之间存在巫术,上述情况会有多好。

答案 4 :(得分:3)

你可以试试这个:

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

获取与您的域名相关联的IP地址。

答案 5 :(得分:1)

我知道这个问题已经很久很久了,但我一直在谷歌搜索同样的东西,并想加入我自己的“黑客”。为此,您的webrequest必须来自外部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;
?>

答案 6 :(得分:0)

如果您的服务器有域名,您可以ping它,或者您可以使用:

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

它将返回您的外部IP地址。

答案 7 :(得分:0)

假设您的PHP在Linux服务器上运行,您可以使用PHP的exec函数调用ifconfig。这将提供公共IP,而无需联系某些外部网站/服务。 E.g:

$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>';
}

请注意,有时作为$命令,您必须指定ifconfig的完整路径。您可以通过执行

找到它
  

whereis ifconfig

从shell提示符

。此外,$ interface应设置为服务器主网络接口的名称,该接口具有到WAN的链接。

在Windows上,您可以使用ipconfig而不是ifconfig(以及相应的调整后的正则表达式)来执行类似的操作。

答案 8 :(得分:0)

此外,您可以通过DNS A记录获取基于主机名或服务器名称的记录:

$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'];

如果其中一个没有提供您想要的内容,您也可以使用SERVER_NAME而不是HTTP_HOST。

但是,这假设您的服务器配置正确与DNS对应。情况可能并非总是如此。使用可能更好的ifconfig查看我的其他答案。

答案 9 :(得分:0)

我认为在其他答案中有很多这方面的代码,但我的答案很简短,但你需要在shell中执行一个命令来获取ip ...

但它短而快,我认为......

php执行bash&gt; bash run&gt; bash get ip&gt; php get ip

echo shell_exec( "dig +short myip.opendns.com @resolver1.opendns.com");
  

对不起我的英语,我希望它对你有所帮助......

参考:How can I get my external IP address in a shell script?

答案 10 :(得分:0)

这是一个旧线程,但是出于其价值,我添加了一个简单的函数。它使用外部服务(看来是不可避免的),但它也提供备份服务以及本地缓存以避免重复的HTTP调用。

/*
USAGE
$ip = this_servers_public_ip(); // Get public IP, and store it locally for subsequent calls.
$ip = this_servers_public_ip(true); // Force remote query and refresh local cache if exists.
*/
function this_servers_public_ip($purge=false) {
    $local = sys_get_temp_dir().'/this.servers.public.ip';
    if ( $purge===true && realpath($local) ) {
        unlink($local);
    }
    if ( realpath($local) ) {
        return file_get_contents($local);
    }
    // Primary IP checker query.
    $ip = trim( file_get_contents('https://checkip.amazonaws.com') );
    if ( (filter_var($ip, FILTER_VALIDATE_IP) !== false) ) {
        file_put_contents($local,$ip);
        return $ip;
    }
    // Secondary IP checker query.
    $ip_json = trim( file_get_contents('https://ipinfo.io') );
    $ip_arr = json_decode($ip_json,true);
    $ip=$ip_arr['ip'];
    if ( (filter_var($ip, FILTER_VALIDATE_IP) !== false) ) {
        file_put_contents($local,$ip);
        return $ip;
    }
    return false; // Something went terribly wrong.
}

答案 11 :(得分:-3)

你试过了吗?

gethostbyname(php_uname('n'));