PHP如何获取系统的本地IP


96

我需要获取像192. *。这样的计算机的本地IP。使用PHP可以吗?

我需要运行脚本的系统的IP地址,但是我不需要外部IP,我需要他的本地网卡地址。

Answers:


111

从CLI

PHP <5.3.0

$localIP = getHostByName(php_uname('n'));

PHP> = 5.3.0

$localIP = getHostByName(getHostName());


2
这是对我有用的解决方案,避免了调用shell,操作系统命令以及各种可能在以后打开安全漏洞或引发奇怪问题的事情。
Dario Fumagalli 2014年

1
最佳响应通常来自简单性。像那样。
m3nda 2014年

1
@ andras.tim我喜欢简单的答案,但是,当我运行您的脚本时,它没有返回我的计算机的IP地址,而是返回了我的虚拟机中使用的IP地址。.但这可能是什么问题?
Scarl

请注意,此方法依赖于DNS正确解析系统主机名设置的任何内容。并非总是如此。
贾斯汀·麦卡勒

3
在云托管环境中,这可能不会返回预期结果。因为每个主机都有两个以上的IP。
Unix再次

60
$_SERVER['SERVER_ADDR']

13
说明:一台计算机可以有多个IP地址。该变量仅用于HTTP,并包含运行虚拟主机的IP地址。考虑到问题的含糊程度,很难说这是否是预期的答案。
阿尔瓦罗·冈萨雷斯

我认为这是正确的,因为您始终需要分配的IP,一个正在响应您。如果没有,您必须使用@ andras.tim的请求,因为它告诉您系统的主要ip。
m3nda 2014年

这正是我想要的,因为我的服务器位于负载平衡器的后面,因此getHostName不会返回站点域名。
Yep_It's_Me

如果您在
Docker

30

这是旧文章,但可以通过以下方式获得:

function getLocalIp()
{ return gethostbyname(trim(`hostname`)); }

例如:

die( getLocalIp() );

在另一个站点上找到它,请不要删除trim命令,否则您将获得计算机名称。

反引号(特殊引号):之所以起作用,是因为PHP会尝试将这些“特殊引号”(反引号)之间的内容作为shell命令运行,并返回结果输出。

gethostbyname(trim(`hostname`));

与执行非常相似(但效率更高):

$exec = exec("hostname"); //the "hostname" is a valid command in both windows and linux
$hostname = trim($exec); //remove any spaces before and after
$ip = gethostbyname($hostname); //resolves the hostname using local hosts resolver or DNS

7
@paul:由于特殊的引号,当您使用普通引号时由于某些原因它不起作用,而当您删除trim命令时,它甚至不起作用。我知道这听起来很奇怪。对此答案不赞成投票是不好的。阅读答案。
Codebeat

2
反引号(`)在PHP中称为执行运算符。您在第一个代码块中所做的工作几乎与exec命令相同。参见PHP:执行操作员-手册
Christiaan

2
并不是最好的主意。gethostbyname返回主机的回送IP(例如127.0.0.1)是可能且有效的。
2014年

2
这对我有很大帮助,我以为会有像$ _SERVER ['REMOTE_ADDR'];这样的简单PHP函数哪个没有用,但是这个解决方案对我有用!
Pini Cheyni

24

试试看(如果您的服务器是Linux):

$command="/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'";
$localIP = exec ($command);
echo $localIP;

9
不完全正确。无法保证eth0是适当的接口。
2014年

谢谢,这对我来说非常有效。能够设置界面很有帮助!
Rahim Khoja

在我的情况下(WiFi局域网中的本地IP),我必须指定wlan0而不是eth0并替换'inet addr:''inet adr:',这可能是由于系统上使用的语言环境(fr_FR)。除此之外,这个答案是我一直在寻找的解决方案。谢谢!
Niavlys

实际上'inet adr:'在我的终端(法语语言环境)中工作良好,但是在PHP脚本中'inet addr:'是正确的值(我猜是英语语言环境)。
Niavlys

20

可以通过以下方式获取本地计算机的默认外部IP地址:

$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_connect($sock, "8.8.8.8", 53);
socket_getsockname($sock, $name); // $name passed by reference

$localAddr = $name;

这个怎么运作:

由于这是UDP,因此socket_connect不会在网络上发送出去。它仅将本地地址和端口分配给套接字。这使我们可以获取本地地址。

此解决方案无需任何网络流量,DNS或命令执行即可工作。

如果没有路由8.8.8.8(例如,您没有互联网连接),它可能不起作用。


3
这个答案比其他答案更好。对$ _SERVER数组的任何依赖都取决于在Apache下运行的数组。这个想法也适用于Cron工作。我使用它仅在服务器在登台或生产LAN上运行时执行某些功能。完善!
2016年

这是一个明智的答案。我在管理Docker容器的脚本中对其进行了调整,以在$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_connect($sock, $this->getDockerMachineIp(), 53);
Docker

我猜它更便携。另外,重要的一点是sockets应该在PHP上安装并启用模块。
Fabio Montefuscolo

是的,非常感谢@Arnaud Le Blanc,它对我非常有帮助,我通过这种技术获得了我的IP地址
Abid Ali,

这就是我想要的。谢谢!
尔兹

15

取决于本地的意思:

如果本地表示执行PHP代码的服务器/系统的地址,则仍有两种方法可以讨论。如果PHP通过Web服务器运行,则可以通过阅读获得服务器地址$_SERVER['SERVER_ADDR']。如果PHP是通过命令行界面运行的,那么您可能必须执行shell执行ipconfig(Windows)/ifconfig(* nix)并grep输出地址。

如果在本地您是指网站访问者的远程地址,而不是他们的外部IP地址(因为您专门说的是192. *),那么您就不走运了。NAT路由的重点是隐藏该地址。您无法识别IP地址后面的单个计算机的本地地址,但是如果有多台计算机从同一IP访问,则有一些技巧(用户代理,可能是mac地址)可以帮助区分。


1
最后但并非最不重要的一点是,ipconfig / ifconfig很可能会返回多个IP地址:因为计算机通常没有一个地址。好答案。
阿尔瓦罗·冈萨雷斯

是的,NAT的全部目的是现在隐藏本地IP,检查出whatismyip.com,他们知道您的内部IP地址,也使用您的移动设备打开此网站,他们也知道您的移动设备的本地IP地址。编辑:我在移动设备上使用JioFi路由器,即时消息在基于Android 9 AOSP的rom上使用移动数据
Rishabh Gusain '19

10

hostname(1)可以告诉IP地址:hostname --ip-address,或者如人所说,最好使用hostname --all-ip-addresses


6

您可以在Linux主机上的CLI中以普通用户身份尝试使用此命令:

function get_local_ipv4() {
  $out = split(PHP_EOL,shell_exec("/sbin/ifconfig"));
  $local_addrs = array();
  $ifname = 'unknown';
  foreach($out as $str) {
    $matches = array();
    if(preg_match('/^([a-z0-9]+)(:\d{1,2})?(\s)+Link/',$str,$matches)) {
      $ifname = $matches[1];
      if(strlen($matches[2])>0) {
        $ifname .= $matches[2];
      }
    } elseif(preg_match('/inet addr:((?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:[.](?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3})\s/',$str,$matches)) {
      $local_addrs[$ifname] = $matches[1];
    }
  }
  return $local_addrs;
}

$addrs = get_local_ipv4();
var_export($addrs);

输出:

array (
  'eth0' => '192.168.1.1',
  'eth0:0' => '192.168.2.1',
  'lo' => '127.0.0.1',
  'vboxnet0' => '192.168.56.1',
)

array('bond0'=>'10.66.42.83','bond1'=>'hosting Ip address','lo'=>'127.0.0.1', )我懂了。我在php文件中添加了此代码,
Straw Hat

好的答案,谢谢。split()自PHP 5.3.0起,该函数已被弃用。因此建议explode()改用
Thanu


4

这非常简单,上面的答案使事情变得复杂。只需使用此方法即可获取本地和公共IP地址。

   <?php 
$publicIP = file_get_contents("http://ipecho.net/plain");
echo $publicIP;

$localIp = gethostbyname(gethostname());
echo $localIp;

?>


1

我摆弄了服务器php的这个问题(从Linux终端运行)

我分解了“ ifconfig”并将其修整为IP地址。

这里是:

$interface_to_detect = 'wlan0';
echo explode(' ',explode(':',explode('inet addr',explode($interface_to_detect,trim(`ifconfig`))[1])[1])[1])[0];

当然,将“ wlan0”更改为所需的网络设备。

我的输出是:

192.168.1.5

0

如果您在OS X上的开发环境中,则通过Wifi连接:

echo exec("/sbin/ifconfig en1 | grep 'inet ' | cut -d ' ' -f2");

0
$_SERVER['SERVER_NAME']

它为我工作。


-4
$_SERVER['REMOTE_ADDR']
  • PHP_SELF 返回当前脚本的文件名以及相对于根目录的路径

  • SERVER_PROTOCOL 返回页面请求协议的名称和修订

  • REQUEST_METHOD 返回用于访问页面的请求方法

  • DOCUMENT_ROOT 返回当前脚本正在其下执行的根目录


完全正确,但也完全与提出的问题无关。-1。
马克·

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.