如何使用PHP获取服务器的本地IP地址?

9
我正在开发一个 PHP 应用程序,它将仅在企业的本地网络上运行。该应用程序将使用我们使用 Stunnix Advanced Webserver 制作的自定义安装程序安装到服务器上。
为了使应用程序更加用户友好,我计划显示服务器的“本地 IP”,以便网络中的其他计算机可以通过在其地址栏中键入此 IP 来轻松访问应用程序。
问题是我无法获取服务器的“本地 IP”。
我尝试过:
SERVER_NAME(仅显示 127.0.0.1)
REMOTE_ADDR(显示客户端外部 IP)
SERVER_ADDR 显示正确的 IP,但只有在我使用 IP 从客户端访问它时才会这样做,这完全违背了它的目的。
我只想在直接通过 http://localhost 访问服务器时显示服务器的“本地 IP”。
我相当确定这是不可能的。但如果可以,请帮忙。
编辑
我正在开发一种跨平台的 PHP 服务器应用程序。我们捆绑 Apache、PHP 安装程序和 SQlite 数据库作为一键安装程序与我们的 PHP 应用程序一起,以尽可能使其用户友好。任何人都可以在运行 Windows、Mac 或 Linux 的计算机上部署它。安装后,当用户在服务器上打开应用程序时,他可以看到可用于连接到此服务器的 IP 地址 [本地 IP] 和端口。该应用程序将仅在本地网络上运行,而不是在互联网上。
它应该像名为 Air Droid 的 Android 应用程序一样显示本地 IP。 屏幕截图:https://lh3.ggpht.com/PmLopRm-Lj9WTnzm2MBI-bTbCLopAyqtd4C_4nvyDwLg8X0QwDbBbEREdWGHG5xku4s
8个回答

12
您面临的问题是这不是一份静态信息。任何一台计算机都可以有多个与多个网络卡相关联的IP地址,其中某些、全部或没有可能在其上提供Web服务。对于您询问操作系统的问题,可能没有单一答案。
如果您的服务器具有简单的单个IP地址配置,则最好硬编码此代码-这肯定是最简单的选项。如果您想要动态确定它,请参考以下几点信息,您会发现这些信息很有用:
- $_SERVER ['HTTP_HOST'] 包含输入浏览器地址栏中以访问该页面所键入的地址。 如果您通过输入(例如)http://192.168.0.1/index.php 来访问该页面,则 $_SERVER ['HTTP_HOST'] 将是 192.168.0.1。 - 如果您使用DNS名称访问页面,则 gethostbyname($_SERVER['HTTP_HOST']); 将将该DNS名称转换为IP地址。 - $_SERVER ['SERVER_NAME'] 包含已在Web服务器配置中配置为其服务器名称的名称。 如果您要使用它,则可以在PHP中直接硬编码。 - $_SERVER ['SERVER_ADDR'] 将包含服务器的主IP地址的操作系统。 这可能是或可能不是用于访问页面的IP地址,也可能是或可能不是绑定到Web服务器的IP地址。 这取决于操作系统和服务器配置。 如果服务器只有一个IP地址,则这可能是一个安全的选择,但也有情况下它可能包含 127.0.0.1。
总之,没有100%可靠的方法可以确定Web服务器的保证工作IP地址,而不需要检查发送到Web服务器以生成您正在创建的页面的信息,正如您所说完全违背了其目的。

谢谢您的建议。它真的很有道理。如果服务器连接到两个网络(例如,笔记本电脑连接到Ethernet和WiFi),选择正确的网络和IP地址将非常不可靠。我没有这么想过。顺便说一下,让用户自己找到他的IP地址会使应用程序变得不那么友好。:( - ajaybc
1
@ajaybc 这就是 DNS 的作用...如果都在本地,你可以直接使用机器名称访问网络;如果是通过互联网访问,就将域名/子域名的 A 记录指向你的 IP 地址即可;-) - DaveRandom

3

解决方案:

  1. 在 PHP 中硬编码(安装后应在脚本中编辑)
  2. 在 Apache 环境中设置一个变量,以便通过 PHP 访问(安装后应将其添加到 Apache 的配置中)
  3. 解析 ifconfig -lipconfig -a 的输出,确定机器的网络接口的 IP 地址,排除环回接口。在最好的情况下,你将收到一个 IP 地址 - 那就是你需要的地址,加上 $_SERVER['SERVER_PORT']。如果你得到多个 IP 地址 - 你可以尝试查询它们所有来检查它们是否在 $_SERVER['SERVER_PORT'] 上响应 HTTP 请求。此外,如果机器在不同的 IP 地址上运行多个 HTTP 服务器,你还可以放置一个带有某种 echo "my application";/ping.php 文件来确定你的 IP 地址。

我会使用第三方库。但是PHP应该能够使用exec()并根据操作系统使用不同的解析算法,例如Windows使用ipconfig -a,Unix使用ifconfig -l等。 - Ilya Sheershoff

2
我非常确定这是不可能的。即使可能,结果也不可靠。
一个服务器可以拥有多个IP地址。此外,在服务器上用于HTTP的IP地址可能与从其他地方到达服务器所使用的IP地址不同(如果涉及反向代理或NAT)。 SERVER_ADDR变量显示用于调用PHP脚本的IP地址;这些信息是从Web服务器传递的,因此对于独立运行的PHP脚本(即从shell中运行的脚本)没有帮助。
让我们从另一个角度来看这个问题。你想解决什么问题?也就是说,为什么你需要服务器的本地IP?与其寻求无法实现的解决方案,不如看一下原始问题,并查看是否存在其他可能的解决方案。
我应该指出,根据您的操作系统,可能有一些方法通过解析诸如ifconfig -a或ip addr之类的shell命令的输出来获取分配给各种接口的IP列表。但是我不知道你的操作系统,所以无法建议哪种方法适合你。
$h = popen("ip addr | awk '/inet/{print$2}'");
$ip_list = array();
while ($ip_list[] = fread($h, 15)) { }
pclose($h);

您可以在PHP中加入更多逻辑,以避免使用管道中的awk,但您已经了解了这个想法。


我正在开发一种跨平台的PHP服务器应用程序。我们将Apache、PHP安装程序和SQlite数据库捆绑在一起,作为一个一键安装程序与我们的PHP应用程序一起提供,以使其尽可能地用户友好。任何人都可以在他们的计算机上部署它。 - ajaybc
好的,如果你甚至不知道人们将在哪个操作系统上运行你的应用程序,或者安全模式是否已打开,那么一个 shell 工具也无法解决这个问题。正如我所说,如果你能描述你试图解决的问题而不是你想出的解决方案,我们可以帮助解决那个问题,而不是帮助实现你的解决方案。 - ghoti

2

如果你想获取类似 192.168.x.x局域网IP地址,可以使用以下代码:

我正在使用这个代码,能够完美地满足我的需求(仅在Windows机器上测试过)。

function getLocalIP(){
    exec("ipconfig /all", $output);
        foreach($output as $line){
            if (preg_match("/(.*)IPv4 Address(.*)/", $line)){
                $ip = $line;
                $ip = str_replace("IPv4 Address. . . . . . . . . . . :","",$ip);
                $ip = str_replace("(Preferred)","",$ip);
            }
        }
    return $ip;
}

echo $ip = getLocalIP(); //This will return: 192.168.x.x (Your Local IP)

希望这能够帮到您。 =)

3
"ipconfig" 仅适用于 Windows 系统,且并不是特别有用。 - kodeart

0
尝试一下: <?php gethostbyname($_SERVER['SERVER_NAME']); 编辑:
有点hacky,但似乎可以工作:
<?php
$str = file_get_contents("http://ip6.me/");
$pattern = "#\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b#";
preg_match($pattern, $str, $matches);
print_r($matches[0]);

但这取决于第三方网站。


很抱歉,这不可行。因为它显示的是127.0.0.1。我想要的是像192.168.1.6那样的IP地址,那是服务器的本地IP。 - ajaybc
我也试了你的修改,但它只获取服务器的外部IP。我需要的是服务器的本地IP。谢谢。 - ajaybc

0

您可以使用以下命令查看所有可用信息:

print_r($_SERVER, 1);

0

尝试使用命令 "ifconfig en1 inet"。

print_r(exec("ifconfig en1 inet"));

输出:- inet 192.168.. netmask 0xffffff00 broadcast 192.168.*.255


ifconfig 不适用于 Windows。 - Osman Khalid

-1

在Windows 10上运行良好,但在Windows 11上有所不同,我必须使用for方法来改进代码并使其更简单。实际上,我将进行一些调整。

$saldo_de_linea = '<br>';
$ipconfig =  ( shell_exec ("ipconfig/all"));
echo $saldo_de_linea;
$d = explode('Physical Address. . . . . . . . .',shell_exec ("ipconfig/all"));
$d1 = explode(':',$d[1]);
echo 'SEGMENTO_A 10: ' . $d1[10];
echo $saldo_de_linea;
echo 'your localhost ip use for xampp is ';
echo $saldo_de_linea;
echo $d1[10];
$mystring = $d1[10];
$findme   = '(';
$pos = strpos($mystring, $findme);
if ($pos === false) {
    echo "La cadena '$findme' no fue encontrada en la cadena '$mystring'";
} else {
    echo "La cadena '$findme' fue encontrada en la cadena '$mystring'";
    echo " y existe en la posición $pos";
}
echo $saldo_de_linea;
$ip_localhost_use_for_xampp = substr($mystring, 0, $pos);
echo $ip_localhost_use_for_xampp; // imprime "nas"

不鼓励只回答代码的答案 - klutt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接