137

How can I identify the server IP address in PHP?

parsaya
  • 67
  • 1
  • 4
pooja
  • 2,334
  • 3
  • 16
  • 16

18 Answers18

199

Like this for the server ip:

$_SERVER['SERVER_ADDR'];

and this for the port

$_SERVER['SERVER_PORT'];
David De Sloovere
  • 3,415
  • 2
  • 24
  • 27
CloudyMarble
  • 36,908
  • 70
  • 97
  • 130
  • 11
    No. On some shared hosts this returns ::1 – TheRealChx101 Aug 02 '14 at 06:18
  • 3
    This could be incorrect depending on the Load Balancer being used in front of your web server. You want the X-Forwarded-For header as well in this scenario: http://en.wikipedia.org/wiki/X-Forwarded-For – akahunahi Aug 25 '14 at 23:04
  • 39
    This is NOT the server address! This is the address the *remote* browser calls the server, which is under control of the remote user. Use the answer by `John K` instead – Ariel Feb 12 '15 at 10:36
  • 1
    This does not give the server ip. For some reason it is giving my local ip – Thomas Williams Jun 28 '17 at 15:11
  • It also doesn't give the php-fpm server address, but is for the associated web server (nginx, apache). So it won't be correct for the mysql-client host specification (user@host). – scipilot Apr 25 '18 at 03:45
  • 1
    It also doesn't work if you invoke it via CLI. As `John K` suggested, it is better to use `gethostbyname(gethostname());` – David Mar 19 '19 at 11:26
  • @TheRealChx101 already pointed the problem with your suggested solution. Since, this is accepted solution, you should either append `@JohnK` solution with appropriate credit or at least link to the existing solution. Cheers! – Fr0zenFyr Jul 05 '19 at 08:31
122

If you are using PHP version 5.3 or higher you can do the following:

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

This works well when you are running a stand-alone script, not running through the web server.

John K
  • 1,257
  • 1
  • 8
  • 2
  • 7
    +1 This is the only solution that will work with the command line. – Adam Elsodaney Nov 09 '14 at 01:52
  • 3
    @andreas It shouldn't. The local hostname should be in the `/etc/hosts` file and will be fast - although it might just be `127.0.0.1`. If it does have to call DNS then it will be slow like you say. – Ariel Feb 12 '15 at 10:39
  • +1 but just a question.. i try it with xampp on a local server and it's return the ip 192.168etc but.. it should be 127.0.0.1 no?? – Andrea Bori Oct 28 '15 at 21:21
  • this works for me but some machine its showing domain name. how to rectify this issue. – Dharani Dharan Dec 17 '15 at 12:54
  • This gives 127.0.0.1 for me. How do I get the public IP? Eg stackoverflow.com = 151.101.193.69 – Drewdavid May 19 '21 at 19:17
21

for example:

$_SERVER['SERVER_ADDR']

when your on IIS, try:

$_SERVER['LOCAL_ADDR']
Flask
  • 4,966
  • 1
  • 20
  • 39
  • 4
    `$_SERVER['LOCAL_ADDR']` is only available under IIS when PHP is running as a CGI module. – Rudi Visser Apr 27 '11 at 07:58
  • @rudi_visser it works with fastcgi as well, but f you connect via locahost, you get ::1 back instead. If you connect via the server's name or ip, you get the real ip back. – starbeamrainbowlabs Jul 21 '12 at 14:01
  • @starbeamrainbowlabs FastCGI *is* CGI :) I meant in contrast to running as an ISAPI module, this was written before the major advent of FastCGI as a stable platform. – Rudi Visser Jul 21 '12 at 17:54
  • @starbeamrainbowlabs anything that looks like ::1 is probably an IP6 address – Toby Allen Dec 20 '12 at 21:24
  • @TobyAllen Thank you :). The odd thing is that my network does not support ipv6, yet my server (windows 7 machine) reports its IP as ::1, the ipv6 loopback address. – starbeamrainbowlabs Dec 21 '12 at 11:26
15

Neither of the most up-voted answers will reliably return the server's public address. Generally $_SERVER['SERVER_ADDR'] will be correct, but if you're accessing the server via a VPN it will likely return the internal network address rather than a public address, and even when not on the same network some configurations will will simply be blank or have some other specified value.

Likewise, there are scenarios where $host= gethostname(); $ip = gethostbyname($host); won't return the correct values because it's relying on on both DNS (either internally configured or external records) and the server's hostname settings to extrapolate the server's IP address. Both of these steps are potentially faulty. For instance, if the hostname of the server is formatted like a domain name (i.e. HOSTNAME=yahoo.com) then (at least on my php5.4/Centos6 setup) gethostbyname will skip straight to finding Yahoo.com's address rather than the local server's.

Furthermore, because gethostbyname falls back on public DNS records a testing server with unpublished or incorrect public DNS records (for instance, you're accessing the server by localhost or IP address, or if you're overriding public DNS using your local hosts file) then you'll get back either no IP address (it will just return the hostname) or even worse it will return the wrong address specified in the public DNS records if one exists or if there's a wildcard for the domain.

Depending on the situation, you can also try a third approach by doing something like this:

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

This has its own flaws (relies on a specific third-party site, and there could be network settings that route outbound connections through a different host or proxy) and like gethostbyname it can be slow. I'm honestly not sure which approach will be correct most often, but the lesson to take to heart is that specific scenarios/configurations will result in incorrect outputs for all of these approaches... so if possible verify that the approach you're using is returning the values you expect.

Ben D
  • 14,321
  • 3
  • 45
  • 59
15

I came to this page looking for a way of getting my own ip address not the one of the remote machine connecting to me.

This will not work for a windows machine.

But in case someone searches for what I was looking for:

#! /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;

(Shamelessly adapted from How to I get the primary IP address of the local machine on Linux and OS X?)

Community
  • 1
  • 1
Dom
  • 2,240
  • 16
  • 22
  • 1
    This is the only option that actually works when running PHP scripts from the shell. Question: when there are multiple active interfaces, how does this decide which address to return? I tested with wired and wireless ethernet connections active, and then with only wireless active, and it returns the wlan ip both times. Good script, thanks! – Ryan Griggs May 20 '17 at 18:18
  • 1
    It does not actually know which one to return. It simply returns the last inet interface from the output of ifconfig, but ignoring 127.0.0.1. If you only have the "usual" interfaces, then it does a pretty good job. It is probably safest if you specify the interface you want "ifconfig wlan0 | ...". This script is by no means perfect but it works in simple settings and it demonstrates how to do this in principle, to be adjusted as needed. – Dom May 24 '17 at 07:36
  • 2
    ifconfig | grep 'inet addr' | cut -d ':' -f 2 | awk '{ print $1 }' | grep -vE '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|127\.)' is my latest revision of this. It filters out all the local ips and only gives you externals – Dom Nov 14 '17 at 13:20
  • 1
    I have multiple network interfaces so I did `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 Jul 25 '19 at 22:16
13

This is what you could use as an adaptation of the above examples without worrying about curl installed on your server.

<?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);
    ?>
Emmanuel Mahuni
  • 1,766
  • 16
  • 16
6

Check the $_SERVER array

echo $_SERVER['SERVER_ADDR'];
Ale
  • 433
  • 3
  • 8
5

If you are using PHP in bash shell you can use:

$server_name=exec('hostname');

Because $_SERVER[] SERVER_ADDR, HTTP_HOST and SERVER_NAME are not set.

jam
  • 3,640
  • 5
  • 34
  • 50
5

The previous answers all give $_SERVER['SERVER_ADDR']. This will not work on some IIS installations. If you want this to work on IIS, then use the following:

$server_ip = gethostbyname($_SERVER['SERVER_NAME']);
qbert220
  • 11,220
  • 4
  • 31
  • 31
2

I found this to work for me: GetHostByName("");

Running XAMPP v1.7.1 on Windows 7 running Apache webserver. Unfortunately it just give my gateway IP address.

Sanford Staab
  • 239
  • 2
  • 10
2

I just created a simple script that will bring back the $_SERVER['REMOTE_ADDR'] and $_SERVER['SERVER_ADDR'] in IIS so you don't have to change every variable. Just paste this text in your php file that is included in every page.

/** IIS IP Check **/
if(!$_SERVER['SERVER_ADDR']){ $_SERVER['SERVER_ADDR'] = $_SERVER['LOCAL_ADDR']; }
if(!$_SERVER['REMOTE_ADDR']){ $_SERVER['REMOTE_ADDR'] = $_SERVER['LOCAL_ADDR']; }
Xander
  • 21
  • 1
1
$serverIP = $_SERVER["SERVER_ADDR"];
echo "Server IP is: <b>{$serverIP}</b>";
Axe
  • 6,285
  • 3
  • 31
  • 38
1

You may have to use $HTTP_SERVER_VARS['server_ADDR'] if you are not getting anything from above answers and if you are using older version of PHP

OpenCode
  • 578
  • 1
  • 5
  • 12
1

You can use https://icanhazip.com and since Cloudflare owned this project sometimes it can be even more reliable.

$my_real_ip = file_get_contents('https://icanhazip.com/');
insign
  • 5,353
  • 1
  • 38
  • 35
1

To accurately get the external IP address, you can call checkip.amazonaws.com, a service provided by Amazon.

$ip = exec("curl https://checkip.amazonaws.com");

As we can see it's such a widespread problem that AWS has created that very tool for the world to use.

I would use that over other similar services, since it's provided by AWS and will probably be around for long.

Wadih M.
  • 12,810
  • 7
  • 47
  • 57
0

Check the $_SERVER array

echo $_SERVER['SERVER_ADDR'];
Gaurang
  • 1,928
  • 18
  • 12
  • 1
    That doesn't find the "real IP", it finds ***arbitrary, unverified HTTP headers anybody may set and anybody may use to spoof their IP if you prefer them.*** If the client is behind a proxy then so be it, don't trust any HTTP headers. This also doesn't fit the question at all. – deceze Apr 03 '13 at 10:15
  • 3
    Can't figure how this answer does not fit the question at all. The question was: "How can I identify the server IP address in PHP?". Either should the OP learn how to ask better, or should you learn how to read a question. Besides, if the client is behind a proxy, you're still screwed no matter what you try from server-side. A totally different scenario is when the server is behind a proxy, since you can check with X-FORWARDED-FOR headers. – Luis Masuelli May 20 '14 at 15:14
  • @deceze `$_SERVER["SERVER_ADDR"]` does not have anything to do with HTTP headers. This is filled by the server software, all HTTP related stuff in $_SERVER is prefixed with HTTP_. https://www.php.net/manual/en/reserved.variables.server.php – poncha Apr 17 '19 at 21:27
  • @poncha My comment pertained to the [original revision](https://stackoverflow.com/posts/15784410/revisions) of this post. – deceze Apr 18 '19 at 05:08
0

Here is one solution when the site is running behind a load-balancer, a reverse proxy server, or a CDN like CloudFront:

$conn = curl_init();
curl_setopt($conn, CURLOPT_URL, 'any.valid.url');
curl_exec($conn);
$WebServerIP = curl_getinfo($conn)['local_ip'];
-1

Like this:

$_SERVER['SERVER_ADDR'];
Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208