如何在PHP中识别服务器IP地址


122

如何识别PHP中的服务器IP地址?


2
您是指请求IP地址还是运行您的应用的计算机的IP?
wosis 2011年

Answers:


175

像这样的服务器IP:

$_SERVER['SERVER_ADDR'];

这是港口

$_SERVER['SERVER_PORT'];

9
在某些共享主机上,它返回:: 1
TheRealChx101

3
这可能是不正确的,具体取决于Web服务器前面使用的负载均衡器。在这种情况下,您还需要X-Forwarded-For标头:en.wikipedia.org/wiki/X-Forwarded-For
Ligemer,2014年

31
这不是服务器地址!这是远程浏览器调用服务器的地址,该地址由远程用户控制。通过使用答案John K,而不是
林依晨

这不给服务器IP。由于某些原因,它给了我当地的IP
Thomas Williams

它还不提供php-fpm服务器地址,但是用于关联的Web服务器(nginx,apache)。因此,对于mysql客户端主机规范(user @ host)而言,它是不正确的。
scipilot

105

如果您使用的是PHP 5.3或更高版本,则可以执行以下操作:

$host= gethostname();
$ip = gethostbyname($host);

当您运行独立脚本而不通过Web服务器运行时,此方法效果很好。


完美,我正在寻找。感谢约翰
弗兰克

6
+1这是唯一适用于命令行的解决方案。
亚当·埃尔索达尼

2
@andreas不应该。本地主机名应该在/etc/hosts文件中,并且应该是快速的(尽管可能只是)127.0.0.1。如果确实必须调用DNS,那么它将像您所说的那样慢。
Ariel 2015年

+1但只是一个问题..我在本地服务器上用xampp尝试了一下,它返回了ip 192.168etc,但是..它应该是127.0.0.1不?
安德里亚·博里

这对我有用,但是有些机器显示域名。如何纠正此问题。
Dharani Dharan 2015年

19

例如:

$_SERVER['SERVER_ADDR']

当您在IIS上时,请尝试:

$_SERVER['LOCAL_ADDR']

2
$_SERVER['LOCAL_ADDR']仅当PHP作为CGI模块运行时,才在IIS下可用。
Rudi Visser

@rudi_visser也可以与fastcgi一起使用,但是如果您通过locahost连接,则会返回:: 1。如果通过服务器的名称或IP连接,则会获得真实IP。
starbeamrainbowlabs 2012年

@starbeamrainbowlabs FastCGI CGI :)我的意思是与以ISAPI模块运行相反,它是在FastCGI作为稳定平台主要出现之前编写的。
鲁迪·维瑟

@starbeamrainbowlabs看起来像:: 1的任何东西都可能是IP6地址
Toby Allen

@TobyAllen谢谢:)。奇怪的是,我的网络不支持ipv6,但是我的服务器(Windows 7计算机)报告其IP为:: 1,即ipv6回送地址。
starbeamrainbowlabs 2012年

13

我来到此页面,是在寻找一种获取我自己的IP地址而不是与我连接的远程计算机的方法。

这不适用于Windows计算机。

但是如果有人搜索我在寻找什么:

#! /usr/bin/php
<?php
$my_current_ip=exec("ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'");
echo $my_current_ip;

(从如何在Linux和OS X上获取本地计算机的主IP地址进行了无耻的修改)


从外壳运行PHP脚本时,这是唯一实际起作用的选项。问题:当有多个活动接口时,如何确定返回哪个地址?我测试了有线和无线以太网连接处于活动状态,然后仅启用了无线连接,并且两次都返回了wlan ip。好的脚本,谢谢!
Ryan Griggs

它实际上并不知道该返回哪一个。它只是从ifconfig的输出返回最后一个inet接口,但忽略了127.0.0.1。如果您只有“常规”界面,那么它做得很好。如果指定想要的接口“ ifconfig wlan0 | ...”,则可能是最安全的。该脚本绝不是完美的,但它可以在简单的设置中工作,并且演示了如何进行此原理,并根据需要进行调整。
Dom

1
ifconfig | grep'inet addr'| 切-d':'-f 2 | awk'{print $ 1}'| grep -vE'^(192 \ .168 | 10 \。| 172 \ .1 [6789] \。| 172 \ .2 [0-9] \。|| 172 \ .3 [01] \。| 127 \。 )”是我对此的最新修订。它过滤掉所有本地ip,只为您提供外部信息
Dom

我有多个网络接口,所以我做了ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | grep -e '192\.168\.1\.'
乔纳森(Jonathan)

10

投票最多的答案都不会可靠地返回服务器的公共地址。通常$_SERVER['SERVER_ADDR']是正确的,但是如果您通过VPN访问服务器,它很可能会返回内部网络地址,而不是公共地址,即使不在同一网络上,某些配置也将完全为空白或指定了其他配置值。

同样,在某些情况下,$host= gethostname(); $ip = gethostbyname($host);由于它同时依赖DNS(内部配置的记录或外部记录)和服务器的主机名设置来推断服务器的IP地址,因此不会返回正确的值。这两个步骤都可能有故障。例如,如果服务器的主机名的格式类似于域名(即HOSTNAME=yahoo.com),那么(至少在我的php5.4 / Centos6设置中)gethostbyname将直接跳转到查找Yahoo.com的地址,而不是本地服务器的地址。

此外,因为 gethostbyname回退到公共DNS记录上的测试服务器具有未发布或不正确的公共DNS记录(例如,您通过localhostIP地址访问服务器,或者如果您使用本地hosts文件覆盖公共DNS ),则您如果没有IP地址(它将仅返回主机名),或者什至更糟的是,它将返回公共DNS记录中指定的错误地址(如果存在)或该域存在通配符。

根据具体情况,您还可以通过以下方法尝试第三种方法:

$external_ip = exec('curl http://ipecho.net/plain; echo');

这有其自身的缺陷(依赖于特定的第三方站点,并且可能存在通过其他主机或代理路由出站连接的网络设置),并且gethostbyname速度可能很慢。老实说,我不确定哪种方法最正确,但是要铭记的是,特定方案/配置将导致所有这些方法的输出不正确...因此,如果可能的话,请验证您所使用的方法是否正确。 using返回您期望的值。


9

这就是您可以用作上述示例的改编而无需担心服务器上安装的curl的原因。

<?php
      // create a new cURL resource
      $ch = curl_init ();

      // set URL and other appropriate options
      curl_setopt ($ch, CURLOPT_URL, "http://ipecho.net/plain");
      curl_setopt ($ch, CURLOPT_HEADER, 0);
      curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);

      // grab URL and pass it to the browser

      $ip = curl_exec ($ch);
      echo "The public ip for this server is: $ip";
      // close cURL resource, and free up system resources
      curl_close ($ch);
    ?>



4

前面的答案都给出$ _SERVER ['SERVER_ADDR']。在某些IIS安装中,这将不起作用。如果要在IIS上使用,请使用以下命令:

$server_ip = gethostbyname($_SERVER['SERVER_NAME']);


2

我刚刚创建了一个简单的脚本,它将在IIS中恢复$ _SERVER ['REMOTE_ADDR']和$ _SERVER ['SERVER_ADDR'],因此您不必更改每个变量。只需将此文本粘贴到每个页面中包含的php文件中即可。

/** IIS IP Check **/
if(!$_SERVER['SERVER_ADDR']){ $_SERVER['SERVER_ADDR'] = $_SERVER['LOCAL_ADDR']; }
if(!$_SERVER['REMOTE_ADDR']){ $_SERVER['REMOTE_ADDR'] = $_SERVER['LOCAL_ADDR']; }

1
$serverIP = $_SERVER["SERVER_ADDR"];
echo "Server IP is: <b>{$serverIP}</b>";

1

$HTTP_SERVER_VARS['server_ADDR']如果您没有从上述答案中得到任何东西,并且您使用的是旧版本的PHP,则可能必须使用


0

检查$ _SERVER数组

echo $_SERVER['SERVER_ADDR'];

1
找不到“真实IP”,而是找到任何人都可以设置的任意未经验证的HTTP标头,如果愿意,任何人都可以使用其IP欺骗。如果客户端位于代理之后,那就不要相信任何HTTP标头。这也根本不适合这个问题。
deceze

2
无法弄清楚这个答案怎么根本不适合这个问题。问题是:“如何识别PHP中的服务器IP地址?”。OP要么应该学习如何更好地提问,要么应该学习如何阅读问题。此外,如果客户端位于代理之后,无论您从服务器端尝试什么,您都仍然会感到困惑。完全不同的情况是服务器位于代理之后,因为您可以使用X-FORWARDED-FOR标头进行检查。
Luis Masuelli 2014年

@deceze $_SERVER["SERVER_ADDR"]与HTTP标头没有任何关系。这是由服务器软件填充的,$ _SERVER中所有与HTTP相关的内容都以HT​​TP_为前缀。php.net/manual/en/reserved.variables.server.php
poncha

@poncha我的评论与这篇文章的原始版本有关。
deceze

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.