Get server ip address in php

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 //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.

Many times we need to get the IP address of the visitor for different purposes. It is very easy to collect the IP address in PHP. PHP provides PHP $_SERVER variable to get the user IP address easily. We can track the activities of the visitor on the website for the security purpose, or we can know that who uses my website and many more.

The simplest way to collect the visitor IP address in PHP is the REMOTE_ADDR. Pass the 'REMOTE_ADDR' in PHP $_SERVER variable. It will return the IP address of the visitor who is currently viewing the webpage.

Note: We can display this IP address on the webpage and also even can store in database for many other purposes such as - for security, redirecting a visitor to another site, blocking/banning the visitor.

Get the IP address of the website

$_SERVER['REMOTE_ADDR'] - It returns the IP address of the user currently visiting the webpage.

For example

Output

But sometimes the REMOTE_ADDR does not return the IP address of the client, and the main reason behind is to use the proxy. In such type of situation, we will try another way to get the real IP address of the user in PHP.

Output

Flowchart:

The flowchart for the above program will be like given below.


Get the IP address of the website

We can also get the IP address of any website by its URL. Pass the URL of the website inside gethostbyname[] function.

For example

Output

IP Address of Google is - 172.217.166.4
IP Address of javaTpoint is - 95.216.57.234

[PHP 4, PHP 5, PHP 7, PHP 8]

gethostbyaddr Get the Internet host name corresponding to a given IP address

Description

gethostbyaddr[string $ip]: string|false

Parameters

ip

The host IP address.

Return Values

Returns the host name on success, the unmodified ip on failure, or false on malformed input.

Examples

Example #1 A simple gethostbyaddr[] example

See Also

  • gethostbyname[] - Get the IPv4 address corresponding to a given Internet host name
  • gethostbynamel[] - Get a list of IPv4 addresses corresponding to a given Internet host name

lukevb_at_iafrica.com

19 years ago

Sometimes when using $_SERVER['HTTP_X_FORWARDED_FOR'] OR $_SERVER['REMOTE_ADDR'] more than 1 IP address is returned, for example '155.240.132.261, 196.250.25.120'. When this string is passed as an argument for gethostbyaddr[] PHP gives the following error: Warning: Address is not a valid IPv4 or IPv6 address in...

To work around this I use the following code to extract the first IP address from the string and discard the rest. [If you wish to use the other IPs they will be in the other elements of the $ips array].

if [strstr[$remoteIP, ', ']] {
    $ips = explode[', ', $remoteIP];
    $remoteIP = $ips[0];
}

Hope this helps someone :]

king dot macro at gmail dot com

17 years ago

The problem of broken DNS servers was causing me a problem because i had a page for user statistics that required around 20 reverse dns lookups to be done, and even as many as 5/6 of them being broken was causing a huge delay in loading the page. so i wrote a function that uses a UDP socket to talk directly to the DNS server [instead of going via the normal gethostbyaddr function] this let me set a timeout.

The only requirement is that your DNS server must be able to do recursive lookups, it wont go to other DNS servers if its told to... and of course you need to know your DNS servers IP address :-]

This could be expanded quite a bit and improved but it works and i've seen quite a few people trying various methods to achieve something like this so i decided to post it here. on most servers it should also be more efficient than other methods such as calling nslookup because it doesn't need to run external programs

Note: I'm more a C person than a PHP person, so just ignore it if anything hasn't been done the *recomended* way :-]

Vincent

3 years ago

I discovered that gethostbyaddr sometimes returned the same host name with some uppercase letters in it and sometimes with all lowercase letters.

example:

d54c34fa1.access.example.com
d54C34FA1.access.example.com

This is probably not the fault of gethostbyaddr, but this can be a problem when comparing or storing, because it will give two entries instead of one.

A simple solution to this is to use strtolower on the host name.

Matt AKA Junkie

18 years ago

Since my little ISP thing isn't globally acceptable, here's an update.

phalkon at nospam dot home dot com

21 years ago

Be cautious when looking up many hostnames.  If your DNS server is slow to respond, you may have to pump up your Max execution time for your scripts, otherwise, it will timeout.  I found that even 3 unresolvable hosts can cause a 30 second delay in processing.

tom

16 years ago

Be careful with the usage of this function - it will slow down a server to a crawl if called a lot and the slowness won't be reflected in any of the obvious places, like CPU usage, apache requests, SQL etc. When you do use it make a special note of where!

oryan at zareste dot com

16 years ago

If all else fails, but you have shell access, Unix/Linux servers can use this for a timeout response:

shell_exec['host -W 2 0.0.0.0'];

Where 0.0.0.0 is of course the IP, and '2' is the number of seconds for the timeout.  This returns a more detailed string of info, with some additional text which might vary depending on the system, so if you want a string with the hostname and nothing else, you'll have to do some substring cutting.  There should be an equivalent of 'host' for Windows users to execute, but it isn't my platform.

Anonymous

1 year ago

There is 1 bug in gethostbyaddr_timeout[] function that king dot macro at gmail dot com posted in the most important line of all, setting the timeout with socket_set_timeout[]. It should be:

@socket_set_timeout[$handle, intdiv[$timeout_ms, 1000], $timeout_ms % 1000];

I'd also make the $dns parameter last and optional and parse it from /etc/resolve.conf [or something else] if not given.

abe at abe2k dot net

19 years ago

gethostbyaddr[] doesn't seem to be able to resolve ip6.int
[ipv6] adresses, so I made a function that can, and works
just like the normal gethostbyaddr[].

You need dig and ipv6calc, dig should come with most
distributions, if not, install bind from //www.isc.org.
ipv6calc can be found at //www.bieringer.de/linux/IPv6/ipv6calc/index.html.

function gethostbyaddr6[$ip6] {
  $ipv6calc = "/bin/ipv6calc";
  $dig = "/usr/bin/dig";
  $file = popen[$ipv6calc." --in ipv6addr --out revnibbles.int ".escapeshellarg[$ip6], r];
  $ip = fread[$file, 128];
  pclose[$file];
  if [[substr[$ip, 0, 5] == "Error"] || [!$ip]] return "Address is not a valid IPv6 address";
  $file = popen[$dig." ptr ".$ip, r];               
   while [!feof [$file]] {
    $buffer = fgets[$file, 128];
    if [substr[$buffer, 0, 1] == ";"] continue;
    $buffer = explode[" ", $buffer];
    if [$buffer[3] == "PTR"] {
     $host = substr[trim[$buffer[4]], 0, -1];
     pclose[$file];
     return $host;
    }
   }
  pclose[$file];
  return $ip6;
}

echo gethostbyaddr6[$_SERVER[REMOTE_ADDR]];

elpmille at indiana dot edu

20 years ago

I previously used something very similar to what posted but found it to be quite tedious for getting the 'nicehost'. This method below is a lot cleaner, and it also works for numeric addresses.

function nicehost[$host] {
    if [ereg['^[[0-9]{1,3}\.]{3}[0-9]{1,3}$', $host]] {
        return[ereg_replace['\.[0-9]{1,3}$', '.*', $host]];
    } else {
        return[ereg_replace['^.{' . strpos[$host, '.'] . '}', '*', $host]];
    }
}

Stuart Macdonald

12 years ago

Here's a simple function that uses Dig to obtain the hostname for a given IP address. If no hostname can be found it returns the IP again.

Works only on linux / unix, or whatever other platform with dig installed as a command line utility.

robbakAgmail_com

14 years ago

it appears that gethostbyname[] fails if the domain name contains unicode. Example:

$ host 10.10.10.128
128.10.10.10.in-addr.arpa domain name pointer PC-de-S\130bastien.flexi.robbak.com.
$ php  

10.10.10.128

gethostbyaddr is listed as unicode compatable in version 6, so a fix may be in the works.

james at trnxs dot net

11 years ago

You should be careful in the use of $_SERVER['HTTP_X_FORWARDED_FOR'], as I discovered, once using Amazon AWS's Elastic Load Balancer's, this value may be a comma separated list of IP addresses and will thusly not compare as conceived in almost every example I have seen posted by users in the comments.

dhjdhj at gmail dot com

11 years ago

I have observed that there are problems with all approaches that use the existence of an IP address to verify that the name being looked up actually exists.

If you're using opendns, then a request to a non-existent server returns an IP address anyway, the address being one for an opendns server. This is process is presumably in place so that errant URLs in browser requests take you to a "legitimate" page, i.e, the openDNS website where they can notify you of a problem.

Unfortunately, that mechanism seems to occur for ANY non-existent hostname. Appending a single period to the hostname does not seem to help.

pulstar at mail dot com

19 years ago

If you need to store an IP addresses in a database, you can convert and store it in an INT type column [4 bytes]. The functions below can convert IP addresses to its integer decimal value and vice-versa.

function ip2dec[$ipaddr] {
  $base=explode[".",$ipaddr];
  $decimal=[double] $base[0]*16777216;
  $decimal+=$base[1]*65536;
  $decimal+=$base[2]*256;
  $decimal+=$base[3];
  if[$decimal>2147483647] {
    $decimal-=4294967296;
  }
  return [int] $decimal;
}

function dec2ip[$dec] {
  if[$dec16777215] {
    $ip=$dec-[intval[$dec/256]*256];
    $dec=[double] intval[$dec/256];
  } else $ip="0";
  if[$dec>65535] {
    $ip=[$dec-[intval[$dec/256]*256]].".".$ip;
    $dec=[double] intval[$dec/256];
  } else $ip="0.".$ip;
  if[$dec>255] {
    $ip=[$dec-[intval[$dec/256]*256]].".".$ip;
    $dec=[double] intval[$dec/256];
  } else $ip="0.".$ip;
  $ip=$dec.".".$ip;
  return [string] $ip;
}

andy at occ dot nu

21 years ago

if the user is sitting behind a proxy server, you can do this;

ps; i use $HTTP_SERVER_VARS["something"] instead of just $something;
you can get most of the $HTTP_SERVER_VARS by just using there $something equivalent, see the manual for that [preserved variables]

Mark in Sussex

11 years ago

If you use gethostbyaddr[] with a bad IP address then it will send an error message to the error log.
If you don't want your error log file getting too big then first check that the IP address is valid.

In the following example I first check if the IP number starts with a number,
if not then don't use gethostbyaddr['..']

marco[DOT]ceppi[@T]seacrow[DOT]org

12 years ago

Anonymous has a good point [though I don't agree with pushing to execution to shell unless I have to. However this is a faster example [explode then loop is a little too intensive for a simple check]



Though to be honest I would use:

reinhard at ess dot co dot at

17 years ago

tried out some of the examples below, but no one worked for me.
[
"host" returns something if domain-name wasn't found
"gethostbyaddr" has a too long  timeout when it fails
"the udp-example" returns some strange characters...
]
so i have changed the "host"-example a little bit. hope someone can need it. [maybe with little changes like without error-description]

grimNOSPAMtraffic at hotNOSPAMmail dot com

19 years ago

If you have found the host of the ip, the shortest way to cut it not to display the full hostname to the public would be:

$host = substr[$host, strpos[$host, "."] + 1];

P.S. strpos[] can also be easily used if you want to put "*" for every simbol you ommit, like so:

$os = strpos[$host, "."];
$host = substr[$host, $os];
$host = str_repeat["*", $os] . $host;

--McTrafik

ven at PragaKhan dot com

20 years ago

$REMOTE_HOST or $_SERVER['REMOTE_HOST'] will give you the reversed ip IF apache is setup to do hostname lookups.

HostnameLookups On

alexey at ozerov dot de

20 years ago

This function seems to be very slow on IIS 4.0 Server [Win32]. I use system call to NSLOOKUP instead to get PC-Hostname:

unset [$execoutput];
exec ["nslookup $IPAdresse 2>nul",$execoutput,$nslookstatus];
if [isset [$execoutput[3]] && ereg ["^Name: *[[A-Za-z0-9]{2,}]\.",$execoutput[3],$regs]]
$nslookname=strtoupper[$regs[1]];
else $nslookname="Unknown";

Note by members: This is not portable to Windows platforms. so you would be better to stay with our function.

billyblue

14 years ago

I just spent a dickens of a time trying to figure out why my gethostbyaddr's were simply failing halfway through.

I'm returning a log of page visits, and with each new IP, I wanted to pull the hostname of the IP. On each report page, I'm pulling 500 lines from my Db, but only maybe 25 IPs on average. Sometimes this report would generate in under 15 seconds, other times it would fail with a connection reset.

It turns out that several of the IPs in my Db looked like this: x.255.x.x. gethostbyaddr really hates that and simply dies when it reaches one of these IPs.

For my case, I purged the Db and prevented the logging of IPs that contain 255.

webmaster at askapache dot com

13 years ago

Here is a simple function I compiled from user-notes that works great.. any improvements?

www.ad-rotator.com

19 years ago

For ad-rotator.com, we need to do a lot of IP lookups, gethostbyaddr is very easy get timed-out and the script stucks there forever. Here is a fail-safe alternative, 1 sec max for timeout per IP.

function ar_gethostbyaddr[$ip] {
  $output = `host -W 1 $ip`;
  if [ereg['.*pointer [[A-Za-z0-9.-]+]\..*',$output,$regs]] {
    return $regs[1];
  }
  return $ip;
}

Matt AKA Junkie

18 years ago

Going through numerous tests, the following results are concluded:

Chủ Đề