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

Leo*_*ang 20 php ip

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

小智 40

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

您可以使用:

$realIP = file_get_contents("http://ipecho.net/plain");
Run Code Online (Sandbox Code Playgroud)

  • 使用 ipecho.net 比解析 HTML 响应要好得多。该答案应被视为新接受的答案。 (3认同)
  • 前两句相互矛盾.不能有"没办法",然后就是"唯一的办法".此外,"ONLY"在那里是一个非常强大的词. (2认同)

phi*_*hag 30

只需查询返回您的IP地址的主机:

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

或者,设置一个只响应IP的服务,并像这样使用它:

$externalIp = file_get_contents('http://yourdomain.example/ip/');
Run Code Online (Sandbox Code Playgroud)

只需回显远程IP地址,或者付某人托管,即可自行设置服务.千万不能擅自使用他人的服务器.以前,这个答案与我的服务有关,现在每秒都会被多次击中.

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

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

  • 哦是的,如果该网站离线怎么办?那是对的,你会被搞死. (13认同)

Pat*_*ore 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;
Run Code Online (Sandbox Code Playgroud)

  • 正如 ip6.me 页面上的描述,您应该使用“ip4.me”网站,因为您(您的客户)的浏览器可能没有 IPv6 连接并在这种情况下显示“找不到页面”。 (2认同)

jet*_*eon 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
Run Code Online (Sandbox Code Playgroud)

IP地址有一个Google公共DNS服务器.我相信他们会在一段时间内运行它.只要它的公共IP地址属于不介意随机连接尝试的人(你自己可能?),那么你在那里使用的地址应该不重要.

这是基于我在Python中遇到类似问题时遇到的答案.


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