Undefined index: HTTP_X_FORWARDED_FOR

i am using the following script for identifying unique IP address

function _ip( )
return ( preg_match( “/^([d]{1,3}).([d]{1,3}).([d]{1,3}).([d]{1,3})$/”, $_SERVER[‘HTTP_X_FORWARDED_FOR’] ) ? $_SERVER[‘HTTP_X_FORWARDED_FOR’] : $_SERVER[‘REMOTE_ADDR’] );

$ip = _ip(); // Get the users IP using the function above
$time = date( ‘d-m-Y’ ); // Get the current date, in the format of: 12-12-2006
$timestamp = time();

bt i am getting the error:

Notice: Undefined index: HTTP_X_FORWARDED_FOR

You are getting that error because HTTP_* whatever does not exist and you are trying to work with it. You need to use “isset” first.

Isnt that deprecated?

What is? HTTP_X_FORWARDED_FOR? X-Forwarded-For is an HTTP Header, in PHP received HTTP headers from the client appear in such a way. So no…

You’re probably thinking of $HTTP_GET_VARS and $HTTP_POST_VARS versus the new $_GET and $_POST.

This is wrong for the reasons that logic_earth specified. This function will give you the originally intended result:

function _ip( )
	return ( (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match('/^(?:(?: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]?)$/D'), $_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'] );

but you shouldn’t use this anyway! I’m not sure if you wrote the original function, so I’ll give you an explanation about the logic behind it (excuse me if I’m too verbose, but this might help others browsing in the future).

As you may know, when a user connects to your web server to request your page, they send along some information about themselves using HTTP headers. This information usually includes data like what languages they speak, what type of data they can handle, what web browser they’re using, etc. In addition to the data in the HTTP headers, you can get some extra information about them by looking at the TCP/IP layer, which you can think of as the inner workings of the internet communication; this information comes from a much deeper within the computer. The information from here includes things like the IP Address, which identifies the other end of the connection on the internet (in reality the meaning of the IP address is much more complicated, but let’s keep it simple). PHP presents information from the HTTP headers and information from the TCP/IP layer in the same place - the $_SERVER superglobal.

You may also know about things called web proxy servers. These are computers that act as relays for web communication. In a normal setting, when the user wants to get your web page, they make a request for the page from their computer - the TCP/IP information and the HTTP headers both come from the user. When using a web proxy, the user connects to the web proxy instead of your web server, and then the web proxy connects to your server on the user’s behalf - it essentially relays information between both ends. In this setting, the TCP/IP information comes from the web proxy rather than the user, but the HTTP headers still come from the user (they are relayed to you).

One thing that web masters like to do (yourself included, apparently) is to log the IP address of users who visit their web pages. This information comes from the TCP/IP layer and is available as $_SERVER[‘REMOTE_ADDR’]. Unfortunately, as you can see from the preceding paragraph, a user who is connecting through a web proxy does not expose their IP address to your server since they are not the ones making the internet connection. To get around this, a lot of proxy servers add an extra line of information in the HTTP headers called X-Forwarded-For, which specifies the IP address of the user using the web proxy. It is available in PHP as $_SERVER[‘HTTP_X_FORWARDED_FOR’]. Some clever web developers, such as the author of that function, decided to take advantage of this and log the IP address specified by X-Forwarded-For when it is available, and the IP address from the TCP/IP layer when it is not available. That is basically what your function is doing.

Now, this is why you shouldn’t be doing this:

Notice that the X-Forwarded-For information is stored in the HTTP headers, added by the web proxy server. Imagine what would happen if a user added this header by themselves, even when they weren’t using a web proxy server. The information stored there could be complete nonsense; it doesn’t even need to be an IP address. In this case, your PHP script will log this fake address and completely ignore the user’s real IP address available in the TCP/IP layer.

You may be wondering why a user would intentionally add a bogus X-Forwarded-For header when they aren’t using a web proxy. It’s quite simple - to take advantage of flawed code like the function you posted. In fact, it’s quite easy to do. I personally forge this header for all of my web browsing; who knows how many scripts log this bogus IP address rather than my real IP address due to faulty logic. In fact, this mistake runs all the way up to some of the most vast content delivery networks - this little trick can effectively bypass country restrictions for multimedia content on several large networks.

Your next question might be why the user doesn’t also forge the IP address from the TCP/IP layer. In short: the way that the internet is designed means that it is impossible to forge this information and also get your PHP script to fall for the trick. Note, though, that the IP address can be hidden or masked by using proxy servers.

The bottom line is this: if you’re going to log a visitor’s IP address, you should be logging both the IP address in $_SERVER[‘REMOTE_ADDR’] and the forwarded IP address in $_SERVER[‘HTTP_X_FORWARDED_FOR’], if it is available. This will give you the most complete picture of the user’s origin. But keep in mind that a user who wants to remain hidden from you can do so with enough effort (e.g. using a web proxy that doesn’t add the X-Forwarded-For header).

$time = date( 'd-m-Y' ); // Get the current date, in the format of: 12-12-2006
$timestamp = time();

//Log $ip here

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
	//Log $forwardedIP here

Sorry for the length of this tome, but I do believe that a thorough understanding of the fundamentals empowers greater decision making. :slight_smile:

Note that X-Forwarded-For may contain a list of addresses as well.