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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7909362/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 03:37:02  来源:igfitidea点击:

How do I get the external IP of my server using PHP?

phpip

提问by Leo Jiang

I often hear people say to use "$_SERVER['SERVER_ADDR']", but that returns the LAN IP of my server (e.g. 192.168.1.100). I want the external IP.

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

回答by Ben

There is NO way to get your underlying IP Address that has been designated by your ISP via conventional PHP if you are using a router. A way to get the external IP is to find a service that will obtain it for you and echo the address back to you. I found a handy service which does just that. http://ipecho.net/

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

You can use:

您可以使用:

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

回答by phihag

Just query a host that returns your IP address:

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

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

or, set up a service that simply echoes just the IP, and use it like this:

或者,设置一个只回显 IP 的服务,然后像这样使用它:

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

Set up the service yourself by simply echoing the remote IP address, or pay someone to host it. Do notuse somebody else's server without permission. Previously, this answer linked to a service of mine that's now being hit multiple times a second.

通过简单地回显远程 IP 地址自行设置服务,或花钱请人托管。千万不能擅自使用他人的服务器。以前,此答案与我的一项服务相关联,该服务现在每秒被多次点击。

Note that in an IP network with one or more NATs, you may have multipleexternal IP addresses. This will give you just one of them.

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

Also, this solution of course depends on the remote host being available. However, since there is no widely implemented standard (no ISP and only some home routers implement UPnP), there is no other wayto get your external IP address. Even if you could talk to your local NAT, you couldn't be sure that there isn't another NAT behind it.

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

回答by Patrick Moore

You could parse it from a service like ip6.me:

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

回答by jeteon

I'm going to add a solution because the others weren't quite right for me because they:

我将添加一个解决方案,因为其他解决方案不太适合我,因为它们:

  • need to be run on a server with a domain name e.g. gethostbyname()(if you think about it, you don't actually have the problem if you know this a priori)
  • can't be used on the CLI (rely on something in $_SERVERto be set by a web server)
  • assume a specific format of ifconfigoutput, which can include multiple non-public interfaces
  • depend on parsing someone's website (who may disappear, change the URL, change the format, start lying to you, etc, all without notice)
  • 需要在具有域名的服务器上运行,例如gethostbyname()(如果你考虑一下,如果你事先知道这一点,你实际上没有问题)
  • 不能在 CLI 上使用(依赖于$_SERVER由 Web 服务器设置的内容)
  • 假设ifconfig输出的特定格式,可以包括多个非公共接口
  • 取决于解析某人的网站(他们可能会消失、更改 URL、更改格式、开始对您撒谎等,所有这些都没有通知)

This is what I would suggest:

这是我的建议:

$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

The IP address there is a Google public DNSserver. I trust they'll be around and running it for a while. It shouldn't really matter what address you use there as long as its a public IP address that belongs to someone who doesn't mind random connection attempts too much (yourself maybe?).

那里的 IP 地址是Google 公共 DNS服务器。我相信他们会在附近运行一段时间。你在那里使用什么地址并不重要,只要它的公共 IP 地址属于不介意太多随机连接尝试的人(可能是你自己?)。

This is based on an answerI came across when I had a similar problem in Python.

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



P.S.: I'm not sure how well the above would work if there is sorcery going on between your machine and the internet.

PS:如果您的机器和互联网之间存在巫术,我不确定上述方法的效果如何。

回答by jakx

You could try this:

你可以试试这个:

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

to get the IP address associated with your domain name.

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

回答by Martin

I know this question is old and long answered, but I was googling for the same thing and want to add my own "hack". For this to work your webrequest has to come from an external IP address or you have to alter $own_urlto a url that does an external request to itself.

我知道这个问题很老而且答案很长,但我在谷歌上搜索同样的东西并想添加我自己的“黑客”。为此,您的 webrequest 必须来自外部 IP 地址,或者您必须更改$own_url为向自身发出外部请求的 url。

The point is, if you let the script do a request to itself than you get it's external IP address.

关键是,如果您让脚本向自身发出请求,那么您将获得它的外部 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;
?>

回答by DarckBlezzer

I think there is much code for this things in others answers, but my answer is short, but you need to execute a command in shell to get the ip...

我认为其他答案中有很多关于这件事的代码,但我的答案很短,但是您需要在shell中执行命令才能获取ip ...

but it is short and fast, I think that...

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

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

php 执行 bash > bash 运行 > bash 获取 ip > php 获取 ip

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

Sorry my for my english, I hope it help all you...

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

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

参考:如何在 shell 脚本中获取我的外部 IP 地址?

回答by Codebeat

If your server have a domain name you can ping it or you can use:

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

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

It will return your outer IP address.

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

回答by Arthur

Assuming your PHP is running on a Linux server you can call ifconfig using PHP's exec function. This will give public IP without need to contact some external website/service. E.g.:

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

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

Note that sometimes as $command you have to specify full path of ifconfig. You can find this by executing

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

whereis ifconfig

ifconfig 在哪里

from shell prompt. Furthermore $interface should be set to the name of your server's main network interface that has the link to the WAN.

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

On Windows you can do something similar of course, using ipconfig instead of ifconfig (and corresponding adjusted regex).

在 Windows 上,您当然可以做类似的事情,使用 ipconfig 而不是 ifconfig (以及相应的调整后的正则表达式)。

回答by Arthur

Also you could get IP via DNS A record based on hostname or server name:

您也可以通过基于主机名或服务器名称的 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'];

You could also use SERVER_NAME instead of HTTP_HOST if one of the two does not give what you want.

如果两者之一没有提供您想要的,您也可以使用 SERVER_NAME 而不是 HTTP_HOST。

However, this is assuming that your server is configured correctly in correspondence with DNS. This may not always be the case. See my other answer using ifconfig that is perhaps better.

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