$_SERVER["REMOTE_ADDR"] gives server IP rather than visitor IP
Asked Answered
php
M

10

66

I'm trying to track IP addresses of visitors. When using $_SERVER["REMOTE_ADDR"], I get the server's IP address rather than the visitor's. I tried this on multiple machines at multiple locations and they all resulted in the exact same IP. Is there some PHP/server settings that could be affecting this?

Malfeasance answered 23/11, 2010 at 23:25 Comment(4)
Can you link us to the site to confirm? Have you also checked the values (IF PRESENT) of $_SERVER['HTTP_CLIENT_IP'] and $_SERVER['HTTP_X_FORWARDED_FOR']?Cari
Yeah, I tried this. I'm going to go ahead and ask the Unix admins what the issue could be. It is not an issue on any of our other servers.Malfeasance
This can be a misconfiguration of the web server or some sort of proxy on the way. The mystery might be solved if you find out who's IP it is :)Evangelist
It happens to me too. I have a VPS with Ubuntu 16.04 and VestaCP installed. If I use HTTP_X_REAL_IP then it's correct. Vesta is using NGINX so I guess that's the problem (reverse proxy)Practise
H
22

When using $_SERVER["REMOTE_ADDR"], I get the server's IP address rather than the visitor's.

Then something is wrong, or odd, with your configuration.

  • Are you using some sort of reverse proxy? In that case, @simshaun's suggestion may work.

  • Do you have anything else out of the ordinary in your web server config?

  • Can you show the PHP code you are using?

  • Can you show what the address looks like. Is it a local one, or a Internet address?

Hagride answered 23/11, 2010 at 23:30 Comment(0)
A
21

$_SERVER['REMOTE_ADDR'] gives the IP address from which the request was sent to the web server. This is typically the visitor's address, but in your case, it sounds like there is some kind of proxy sitting right before the web server that intercepts the requests, hence to the web server it appears as though the requests are originating from there.

Acuminate answered 23/11, 2010 at 23:29 Comment(3)
I have developed a LIKE SYSTEM where I get real IP of users. Now, I'm facing one issue. I'm connected to home wi-fi. When I click on LIKE button on laptop it works. When I check same in different browser, it works. But, When I open site on my mobile then two IP register in my DB. One is router IP and other one is mobile's IP. But, mobile IP changes in every few seconds. SO, my system thinks that it's different person and count vote from same person as different person.Doradorado
I think it is generally agreed that using IP address for any sort of ID of users is a very bad idea as there are so many ways that the IP address will be wrong, change, duplicated. Find another mechanism. @KalpeshSinghFrae
Thanks for your reply. I will find a better solution soon.Doradorado
P
9

Look no more for IP addresses not being set in the expected header. Just do the following to inspect the whole server variables and figure out which one is suitable for your case:

print_r($_SERVER);
Prebo answered 20/7, 2013 at 22:35 Comment(1)
i found what i was looking for ths way it was: HTTP_X_REAL_IP : json_encode($_SERVER) <- if you need to log itGravitation
M
4
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
  $IP = $_SERVER['HTTP_CLIENT_IP'];
} else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  $IP = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
  $IP = $_SERVER['REMOTE_ADDR']; 
}
Magdalen answered 20/4, 2022 at 11:57 Comment(1)
explanation pleasee..... for more better understandingSacrarium
A
2

Replacing:

$_SERVER["REMOTE_ADDR"];

With:

$_SERVER["HTTP_X_REAL_IP"];

Worked for me.

Alvinia answered 26/8, 2017 at 1:45 Comment(1)
Only do this if you are sure your reverse proxy sets this header. Don't accept arbitrary HTTP headers from clients.Gadget
N
0

Try this

$_SERVER['HTTP_CF_CONNECTING_IP'];

instead of

$_SERVER["REMOTE_ADDR"];
Northeaster answered 20/1, 2020 at 7:14 Comment(0)
H
0

If you are using Cloudflare then this is always the Cloudflare IP address from the node which is serving you.

In this case you get the real IP address from the $_SERVER['HTTP_FORWARDED_FOR'] entry as described in the the other answers.

Hicks answered 25/2, 2021 at 13:49 Comment(0)
U
0

if your site is behind cloudflare, you can use another header provided by cloudflare itself:

$_SERVER['HTTP_CF_CONNECTING_IP']

or if you are using Laravel

$request->server('HTTP_CF_CONNECTING_IP');

read more about it here:

How to get real client IP behind Cloudflare in Laravel / PHP

Uncircumcised answered 31/3, 2022 at 7:12 Comment(0)
K
0

#php 7.x short condition syntax.

<?php
$ip = isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);
echo "The user IP Address is - ". $ip;
?>

from https://www.delftstack.com/howto/php/php-get-user-ip/

Khrushchev answered 18/5, 2022 at 15:39 Comment(6)
Watch out for PHP 7.4, this is deprecated.Cuddle
@Cuddle what specifically is deprecated ?Lyontine
@mfort the left-associative ternary operator Read more about it here: wiki.php.net/rfc/ternary_associativityCuddle
@Cuddle But if I add parentheses as the second example in https://wiki.php.net/rfc/ternary_associativity#proposal for example $ip = (isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : isset($_SERVER['HTTP_X_FORWARDED_FOR'])) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; It will work?Lyontine
@mfort Yes, but I would place the parenthesis in the last block, as you already one check in the left block. The rest is just a fallback. $ip = isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);`Cuddle
As mentioned by deceze under another answer do not use this if your website is not behind a known proxy to you (e.g. cloudflare) headers with HTTP_ prefix can be set from client (even with a simple javascript), and if you know the proxy, you definitely will not need to check other headers either.Publishing
G
0

Enable remoteIP module in your Apache server

a2enmod remoteip

Restart Apache: /etc/init.d/apache2 restart

Gawain answered 2/2, 2023 at 5:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.