There may be many situations in which you will need to know your visitors' IP address and use it to protect your website better. This is often the case for a dynamic website on which you can set up forms, surveys, or protected areas. In an example of a survey, it is not uncommon to allow each user to participate only once, and you would use the visitors' IP address to apply such a limitation. Accessing this information in PHP is very simple since the IP address is directly accessible in the global variable $_SERVER. And more precisely $_SERVER['REMOTE_ADDR'].
Let's create a function to retrieve and return your visitor's IP address:
function getVisitorIp() {
// Get the client's IP address from the REMOTE_ADDR variable
$ address = $_SERVER['REMOTE_ADDR'];
return $address;
}
For servers hosted behind a proxy or firewall
If the function described above works perfectly on your development server, it may no longer work for your production server if it is located behind a proxy or a firewall. As its name indicates, a proxy acts as a client for your server and replaces the real client's IP address. Hence the function we have written above will return the proxy's IP address and not the visitor's.
Since HTTP requests are stateless, the proxy doesn't memorize each request's session state, so it has to find a way to associate the original IP address with each request. Most proxies do this by adding an HTTP header.
Here's what works for most proxies: first search if an HTTP_X_FORWARDED_FOR header exists, as it is the most commonly used header. If not, then look for HTTP_CLIENT_IP. Finally, if neither exists, the function should return the address contained in the REMOTE_ADDR variable.
function getVisitorIp() {
// Look for HTTP_X_FORWARDED_FOR header
if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
$address = $_SERVER['HTTP_X_FORWARDED_FOR'];
// Look for HTTP_CLIENT_IP header
}elseif(!empty($_SERVER['HTTP_CLIENT_IP'])){
$ address = $_SERVER['HTTP_CLIENT_IP'];
// Get the client's IP address from the REMOTE_ADDR variable
}else{
$ address = $_SERVER['REMOTE_ADDR'];
}
return $address;
}
This works in most cases, but if your server is hosted behind a proxy that uses another HTTP header, you will have to find it by searching in the request headers. For example, you can create a temporary script to save all the headers of a request in a temporary file on your server, access this script from your computer, and then search your public IP address in this file to deduce which header is used. Once you find the HTTP header used by your specific proxy, you can add it to the function above.
What about visitors behind a VPN?
Some visitors connect to the Internet through a VPN service to secure their connections to a certain extent. The IP address you can get from your server is the VPN's, not the visitors'. There is no way to obtain the original IP address.
One of the notable consequences is that several of your visitors could use the same VPN service and appear to have the same IP address to your server. To continue protecting your site, before filtering by IP address, you must be able to determine if the IP address belongs to a VPN, and if so, use another means of filtering (such as cookies, for example).
How to detect if a visitor is behind a VPN?
VPN servers regularly renew their IP addresses, making it very difficult for anyone to write and keep up to date a script to check if your visitor is behind a VPN. Therefore, it is necessary to use an external service, such as Abstract API, which provides this information through its geolocation service.
Start by creating a free account, which generates your private key. Then call the API with your API key and the visitor's IP address as parameters, and look at the security field in the response:
function callAbstractApi($api_key, $address) {
$ch = curl_init('https://ipgeolocation.abstractapi.com/v1/?api_key='.$api_key.'&ip_address='.address);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
$data = curl_exec($ch);
curl_close($ch);
return json_decode($data);
}
$api_key = 'your_private_api_key';
$address = getVisitorIp();
$data = callAbstractApi($api_key, $address);
// Checks if the user is behing a VPN
if($data['security']['is_vpn']) {
echo 'User IP is hidden!';
}
There may be many situations in which you will need to know your visitors' IP address and use it to protect your website better. This is often the case for a dynamic website on which you can set up forms, surveys, or protected areas. In an example of a survey, it is not uncommon to allow each user to participate only once, and you would use the visitors' IP address to apply such a limitation. Accessing this information in PHP is very simple since the IP address is directly accessible in the global variable $_SERVER. And more precisely $_SERVER['REMOTE_ADDR'].Let's create a function to retrieve and return your visitor's IP address:
Frequently Asked Questions
What is $_SERVER['REMOTE_ADDR'] in PHP?
$_SERVER['REMOTE_ADDR'] is a PHP superglobal variable that holds the IP address of the client making the current request. It is the simplest way to get a visitor's IP address and works reliably for direct connections. However, it returns the IP of the last connection point to your server, which may be a proxy rather than the actual visitor.
How do I get the real IP address when a visitor is behind a proxy?
When a visitor connects through a proxy, the original IP is usually passed in the HTTP_X_FORWARDED_FOR or HTTP_CLIENT_IP headers. The recommended approach is to check those headers first and fall back to REMOTE_ADDR if they are empty. Check the headers in priority order: HTTP_X_FORWARDED_FOR, then HTTP_CLIENT_IP, then REMOTE_ADDR.
Can HTTP_X_FORWARDED_FOR be spoofed in PHP?
Yes. Unlike REMOTE_ADDR, which reflects the actual TCP connection and cannot be spoofed, the HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP headers are set by the client and can be manipulated. For security-sensitive use cases such as rate limiting or fraud detection, you should only trust these headers if they come from a known, trusted proxy you control.
Can PHP detect if a visitor is using a VPN?
PHP alone cannot detect VPN usage — it can only read the IP address presented by the client. To detect VPNs, you need to pass the IP address to an external security API, such as Abstract's IP Geolocation API, which returns a security field indicating whether the IP belongs to a VPN, proxy, or Tor node. The guide demonstrates this using a PHP cURL request to the API.
How do I call an IP geolocation API from PHP?
Use PHP's cURL extension to make an HTTP GET request to the API endpoint, passing the visitor's IP and your API key as query parameters. Parse the JSON response with json_decode() to access fields like country, city, or VPN status. This approach is covered in the guide with a working code example using Abstract's IP Geolocation API.
When should I use IP address detection in a PHP application?
Common use cases include security filtering, limiting survey or contest participation to one entry per IP, geo-targeted content delivery, and fraud detection. The guide specifically highlights restricting participation and verifying whether a visitor is masking their identity through a VPN. For production applications, pairing basic IP retrieval with a geolocation or security API gives you richer signals than the raw IP alone.