【问题标题】:PHP how to get local IP of systemPHP如何获取系统的本地IP
【发布时间】:2011-03-14 05:56:56
【问题描述】:

我需要获取计算机的本地 IP,例如 192.*.... 用 PHP 可以吗?

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

【问题讨论】:

    标签: php ip-address


    【解决方案1】:

    从命令行

    PHP

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

    PHP >= 5.3.0

    $localIP = getHostByName(getHostName());

    【讨论】:

    • 这是对我有用的解决方案,它避免了调用 shell、操作系统命令和各种可能打开安全漏洞或以后引发奇怪问题的东西。
    • 最佳响应通常伴随着简单性。就这样。
    • @andras.tim 我喜欢简单的答案,但是当我运行您的脚本时,它没有返回我机器的 IP 地址,而是返回了我的虚拟机中使用的 IP 地址。但是可能是什么问题?
    • 请注意,这种方法依赖于 DNS 正确解析系统主机名设置的任何内容。情况并非总是如此。
    • 在云主机环境中,这可能不会返回预期的结果。因为每个主机都有超过 2 个 IP。
    【解决方案2】:
    $_SERVER['SERVER_ADDR']
    

    【讨论】:

    • 澄清:一台电脑可以有多个IP地址。这个变量是 HTTP-only 并且包含虚拟主机运行的 IP 地址。考虑到这个问题的含糊程度,很难说这是否是预期的答案。
    • 我认为这是正确的,因为您始终需要分配的 ip,那个正在响应您。如果没有,你必须使用@andras.tim 的 asnwers,因为它告诉你系统的主 ip。
    • 这正是我想要的,因为我的服务器位于负载均衡器后面,所以getHostName 不会返回站点域名。
    • 如果您在 docker 容器中运行,这将不起作用
    【解决方案3】:

    这是一篇旧帖子,但请使用:

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

    例如:

    die( getLocalIp() );
    

    在另一个站点上找到它,不要删除修剪命令,否则你会得到计算机名称。

    BACKTICKS(特殊引号): 它之所以有效,是因为 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
    

    【讨论】:

    • @paul:由于特殊引号,当您使用普通引号时,由于某种原因它不起作用,当您删除修剪命令时它甚至不起作用。我知道这听起来很奇怪。对此答案投反对票并不好。阅读答案。
    • 反引号 (`) 在 PHP 中称为执行运算符。您在第一个代码块中所做的几乎与 exec 命令相同。见PHP: Execution Operators - Manual
    • 并不是最好的主意。 gethostbyname 可以为主机返回一个环回 IP(例如 127.0.0.1)并且有效。
    • 这对我很有帮助,我认为会有像 $_SERVER['REMOTE_ADDR']; 这样的简单 PHP 函数不起作用,但这个解决方案对我有用!!!
    【解决方案4】:

    获取本地机器的外部 IP 地址的可靠方法是查询路由表,尽管我们在 PHP 中没有直接的方法。

    但是,我们可以通过将 UDP 套接字绑定到公共地址并获取其地址来让系统为我们执行此操作:

    $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
    
    // This is the local machine's external IP address
    $localAddr = $name;
    

    socket_connect 不会引起任何网络流量,因为它是一个 UDP 套接字。

    【讨论】:

    • 这个答案比其他答案好得多。对 $_SERVER 数组的任何依赖都依赖于在 Apache 下运行。这个想法也适用于 cron 作业。如果服务器在登台或生产 LAN 上运行,我只使用它来执行某些功能。完美!
    • 这是一个优雅的答案。我在管理 docker 容器的脚本中对其进行了调整,以获取我的主机在 docker 网络上的 ip:$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_connect($sock, $this->getDockerMachineIp(), 53);
    • 我猜它更便携。另外,重要的是要提到 sockets 模块应该在 PHP 上安装和启用。
    • 是的,非常感谢@Arnaud Le Blanc,它对我很有帮助,我通过这种技术获得了我的 IP 地址
    【解决方案5】:

    试试这个(如果你的服务器是 Linux):

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

    【讨论】:

    • 不完全正确。不能保证eth0 是合适的接口。
    • 谢谢,这对我来说非常有效。能够设置界面有帮助!
    • 在我的情况下(WiFi 本地网络中的本地 IP)我必须指定 wlan0 而不是 eth0 并将 'inet addr:' 替换为 'inet adr:',可能是由于我使用的语言环境系统(fr_FR)。除此之外,这个答案是我正在寻找的解决方案。谢谢!
    • 实际上'inet adr:' 在我的终端(法语语言环境)中工作,但在PHP 脚本中'inet addr:' 是正确的值(我猜是英语语言环境)。
    【解决方案6】:

    取决于你所说的本地:

    如果本地是指执行 PHP 代码的服务器/系统的地址,那么仍有两种途径可以讨论。如果 PHP 正在通过 Web 服务器运行,那么您可以通过阅读 $_SERVER['SERVER_ADDR'] 来获取服务器地址。如果 PHP 是通过命令行界面运行的,那么您可能需要 shell 执行 ipconfig (Windows) / ifconfig (*nix) 并用 grep 查找地址。

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

    【讨论】:

    • 最后但同样重要的是,ipconfig/ifconfig 很可能会返回多个 IP 地址:因为计算机通常没有一个地址。很好的答案。
    • 是的,NAT 的全部意义在于隐藏本地 IP 现在查看 whatismyip.com 他们知道您的内部 IP 地址,也使用您的手机打开此网站,他们也知道您的手机本地 IP 地址。编辑:我使用 JioFi 路由器,在移动即时通讯上使用基于 Android 9 AOSP 的 rom 上的移动数据
    【解决方案7】:

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

    【讨论】:

      【解决方案8】:

      您可以作为普通用户在 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 文件中添加了这段代码,
      • 好答案,谢谢。从 PHP 5.3.0 起,split() 函数已被弃用。所以建议改用explode()
      【解决方案9】:

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

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

      【讨论】:

        【解决方案10】:
        $localIP = gethostbyname(trim(exec("hostname")));
        

        我在 Windows pc 上尝试过,它可以工作,并且还认为可以在 Linux 上工作。

        【讨论】:

          【解决方案11】:

          你可以使用这个 php 代码:

          $localIP = getHostByName(getHostName());
            
          // Displaying the address 
          echo $localIP;
          

          如果你想获得系统的 ipv4,试试这个:

          shell_exec("ip route get 1.2.3.4 | awk '{print $7}'")
          

          【讨论】:

            【解决方案12】:

            这很容易。您可以通过这个简单的代码获取主机名。

            $ip = getHostByName(getHostName());
            

            或者您也可以使用$_SERVER['HTTP_HOST'] 来获取主机名。

            【讨论】:

              【解决方案13】:
              $_SERVER['SERVER_NAME']
              

              它对我有用。

              【讨论】:

                【解决方案14】:

                我为服务器端 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
                

                【讨论】:

                  【解决方案15】:

                  对于 Windows:

                  exec('arp -a',$sa);
                  $ipa = [];
                  foreach($sa as $s)
                      if (strpos($s,'Interface:')===0)
                          $ipa[] = explode(' ',$s)[1];
                  
                  print_r($ipa);
                  

                  $ipa数组返回系统的所有本地IP

                  【讨论】:

                    【解决方案16】:

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

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

                    【讨论】:

                      【解决方案17】:

                      在窗口中

                      $exec = 'ipconfig | findstr /R /C:"IPv4.*"';
                      exec($exec, $output);
                      preg_match('/\d+\.\d+\.\d+\.\d+/', $output[0], $matches);
                      print_r($matches[0]);
                      

                      【讨论】:

                        【解决方案18】:
                        $_SERVER['REMOTE_ADDR']
                        
                        • PHP_SELF 返回当前脚本的文件名以及相对于根目录的路径

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

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

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

                        【讨论】:

                        • 都是正确的,但也与所提出的问题完全无关。 -1.
                        【解决方案19】:

                        试试这个

                        $localIP = gethostbyname(trim('hostname'));
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2014-06-05
                          • 1970-01-01
                          • 1970-01-01
                          • 2011-01-20
                          相关资源
                          最近更新 更多