09-09-2020, 04:08 AM
How to Get the Client User IP Address in PHP
<div style="margin: 5px 5% 10px 5%;"><img src="https://www.sickgaming.net/blog/wp-content/uploads/2020/08/how-to-get-the-client-user-ip-address-in-php.jpg" width="550" height="475" title="" alt="" /></div><div><p>Last modified on August 13th, 2020.</p>
<p>This is fairly a straightforward topic. Just a few lines of PHP code will do the work of getting the client user IP address. Most of the times it is true, it is all about a few lines of PHP script.</p>
<p>Sometimes things get tricky. We shall see about those things and also an other aspect like the privacy issue involved with it.</p>
<p>Following one line PHP code will get you the client user’s IP address. Then why all the fuss? Read through the article and you will know about it.</p>
<pre class="prettyprint lang-php">$_SERVER['REMOTE_ADDR'];
</pre>
<p>$_SERVER is a <a href="https://phppot.com/php/power-of-php-arrays/">PHP array</a> which is set by the server. Depending on this one line PHP code may not yield the best results in many a situation. For example, if a client is behind a proxy server, then this variable will not be suitable. Also be aware that, these headers can be easily spoofed by the users by setting an IP address themselves.</p>
<p>Following PHP script covers majority of the scenario and returns the user’s IP address.</p>
<pre class="prettyprint lang-php"><?php class Request
{ /** * Retrieves IP address set in the request header. * * Each ISPs sets them following their own logic. There is also a possibility for the user * to easily spoof their IP address. * * So using this for mission critical situations is not advisable. * If you are getting the IP address for casual logging purposes, then this is fine. */ public function getIpAddress() { $ipAddress = ''; if (! empty($_SERVER['HTTP_CLIENT_IP']) && $this->isValidIpAddress($_SERVER['HTTP_CLIENT_IP'])) { // check for shared ISP IP $ipAddress = $_SERVER['HTTP_CLIENT_IP']; } else if (! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { // check for IPs passing through proxy servers // check if multiple IP addresses are set and take the first one $ipAddressList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); foreach ($ipAddressList as $ip) { if ($this->isValidIpAddress($ip)) { $ipAddress = $ip; break; } } } else if (! empty($_SERVER['HTTP_X_FORWARDED']) && $this->isValidIpAddress($_SERVER['HTTP_X_FORWARDED'])) { $ipAddress = $_SERVER['HTTP_X_FORWARDED']; } else if (! empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && $this->isValidIpAddress($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) { $ipAddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP']; } else if (! empty($_SERVER['HTTP_FORWARDED_FOR']) && $this->isValidIpAddress($_SERVER['HTTP_FORWARDED_FOR'])) { $ipAddress = $_SERVER['HTTP_FORWARDED_FOR']; } else if (! empty($_SERVER['HTTP_FORWARDED']) && $this->isValidIpAddress($_SERVER['HTTP_FORWARDED'])) { $ipAddress = $_SERVER['HTTP_FORWARDED']; } else if (! empty($_SERVER['REMOTE_ADDR']) && $this->isValidIpAddress($_SERVER['REMOTE_ADDR'])) { $ipAddress = $_SERVER['REMOTE_ADDR']; } return $ipAddress; } /** * To validate if an IP address is both a valid and does not fall within * a private network range. * * @access public * @param string $ip */ public function isValidIpAddress($ip) { if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) { return false; } return true; } } </pre>
<p>There are many options given all through this article to get the client user’s IP address. This is the best among all the possibilities given, but I highly recommend you to read the section “IP address reliability” below.</p>
<h3>Flowchart to get client user’s IP address</h3>
<p>I have tried my best minimize the flowchart. Please do not look for diagrammatic accuracy. It is just an attempt to present the above PHP script in a flowchart model. But after drawing I realized that the above PHP script is easier to understand than this flowchart ?</p>
<p><img loading="lazy" class="alignnone size-large wp-image-11823" src="https://phppot.com/wp-content/uploads/2020/08/flowchart-get-client-user-ip-address-php-550x475.jpg" alt="flowchart to get client user ip address in php" width="550" height="475" srcset="https://phppot.com/wp-content/uploads/2020/08/flowchart-get-client-user-ip-address-php-550x475.jpg 550w, https://phppot.com/wp-content/uploads/20...00x259.jpg 300w, https://phppot.com/wp-content/uploads/20...68x664.jpg 768w, https://phppot.com/wp-content/uploads/20...ss-php.jpg 1400w" sizes="(max-width: 550px) 100vw, 550px"></p>
<h2>Minimal code to get user’s IP address</h2>
<p>Below one line code will work in most of the situation. Read the ‘IP address reliability’ section below, must. It will give you a good idea.</p>
<pre class="prettyprint lang-php">$ipAddress = $_SERVER['REMOTE_ADDR']?:($_SERVER['HTTP_X_FORWARDED_FOR']?:$_SERVER['HTTP_CLIENT_IP']); </pre>
<h2>Get user’s IP address for CloudFlare hosted websites</h2>
<p>I have taken CloudFlare as example. There are many similar services. You need to talk to that service provider to know which request header they are setting and get the IP address accordingly.</p>
<p>When the website is hosted using CloudFlare service, <code>$_SERVER['REMOTE_ADDR']</code> will return the CloudFlare server’s IP address and not the user’s IP address. So in such a situation, you can make use of the variable set by the CloudFlare server to get the IP address.</p>
<pre class="prettyprint lang-php">if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) { $_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"]; $ipAddress = $_SERVER['REMOTE_ADDR'];
} </pre>
<h2>IP address reliability</h2>
<p><code><a href="https://www.php.net/manual/en/reserved.variables.server.php">$_SERVER</a>['REMOTE_ADDR']</code> is the most reliable variable from the above list of variables. <code>REMOTE_ADDR</code> may not contain the real IP address of the TCP connection as well. It depends on the SAPI configuration.</p>
<p>If the user is behind a proxy server, <code>HTTP_X_FORWARDED_FOR</code> will be set. But this can be easily spoofed by the user by setting an IP address he wishes to expose.</p>
<p>Even the variable <code>X-Forwarded-For</code> or the Client-IP can be set by the user to any value he wishes. So, when you maintain a log of user’s IP address, it is better to store the IP address that is returned by <code>$_SERVER['REMOTE_ADDR']</code> also.</p>
<p>Take an example of a <a href="https://phppot.com/php/simple-php-shopping-cart/">shopping cart</a>. You may display the product price according to the user’s country. In such a scenario, you may use the user’s IP address to determine the user’s country. In such a scenario, the code to get user’s IP address should be fool-proof.</p>
<p>So in summary, if you are building a mission critical application that depends on the user’s IP address, then this is not the way to go. For audit log of the user’s IP address, this may suffice. In essence, understand each line of these PHP code and variables used. Know your use-case well and use it accordingly.</p>
<h2>IP address field length</h2>
<p>When you are storing the IP address in the database, remember to have the field size as 45 for single IP. Because there is a possibility for IPv6 IP addresses. It its full form the IPv6 IP address can be 45 characters in length.</p>
<h2>How to get the IP address of a host</h2>
<p>Using a hostname, we can get the server’s IP address using the PHP’s built-in function <code>gethostbyname</code>. This returns the IPv4 address for the host given in argument.</p>
<pre class="prettyprint lang-php">$ipAddress = gethostbyname('www.example.com');
</pre>
<p>The reverse is possible too by using <code>gethostbyaddr()</code>.</p>
<h2>Client user’s IP address and privacy issues</h2>
<p>Client’s IP address can be considered as private information in certain legislation. It depends on the land of law. Internet is public in general. You never know from which geographic region you will get users.</p>
<p>As per GDPR (Article 4, Point 1; and Recital 49), IP address is a personal data. I would suggest to inform the user and get consent to log the IP address. Also, call it out explicitly in your “Privacy Policy” document.</p>
<p>Explicitly state that you are collecting and logging the client user’s IP address and the reason for doing so.</p>
<h2>Conclusion</h2>
<p>Understand your use-case well. A good understanding of the scenario in which you are going to get and use the client user’s IP address is important. Then understand that the end user can easily spoof his IP address and present you something else. Third understand each line of the code, the server variables, from where the IP address is fetched, who sets it etc. Then decide how it will impact your use-case. Last but not the least, explicitly call out in your privacy policy that you are getting the client user’s IP address and storing it. Also state why you are doing it. As per GDPR, IP address is user’s personal information and so it would be better to get user’s consent before processing it.</p>
<p> <!-- #comments --> </p>
<div class="related-articles">
<h2>Popular Articles</h2>
</p></div>
<p> <a href="https://phppot.com/php/how-to-get-the-client-user-ip-address-in-php/#top" class="top">↑ Back to Top</a> </p>
</div>
https://www.sickgaming.net/blog/2020/08/...ss-in-php/
<div style="margin: 5px 5% 10px 5%;"><img src="https://www.sickgaming.net/blog/wp-content/uploads/2020/08/how-to-get-the-client-user-ip-address-in-php.jpg" width="550" height="475" title="" alt="" /></div><div><p>Last modified on August 13th, 2020.</p>
<p>This is fairly a straightforward topic. Just a few lines of PHP code will do the work of getting the client user IP address. Most of the times it is true, it is all about a few lines of PHP script.</p>
<p>Sometimes things get tricky. We shall see about those things and also an other aspect like the privacy issue involved with it.</p>
<p>Following one line PHP code will get you the client user’s IP address. Then why all the fuss? Read through the article and you will know about it.</p>
<pre class="prettyprint lang-php">$_SERVER['REMOTE_ADDR'];
</pre>
<p>$_SERVER is a <a href="https://phppot.com/php/power-of-php-arrays/">PHP array</a> which is set by the server. Depending on this one line PHP code may not yield the best results in many a situation. For example, if a client is behind a proxy server, then this variable will not be suitable. Also be aware that, these headers can be easily spoofed by the users by setting an IP address themselves.</p>
<p>Following PHP script covers majority of the scenario and returns the user’s IP address.</p>
<pre class="prettyprint lang-php"><?php class Request
{ /** * Retrieves IP address set in the request header. * * Each ISPs sets them following their own logic. There is also a possibility for the user * to easily spoof their IP address. * * So using this for mission critical situations is not advisable. * If you are getting the IP address for casual logging purposes, then this is fine. */ public function getIpAddress() { $ipAddress = ''; if (! empty($_SERVER['HTTP_CLIENT_IP']) && $this->isValidIpAddress($_SERVER['HTTP_CLIENT_IP'])) { // check for shared ISP IP $ipAddress = $_SERVER['HTTP_CLIENT_IP']; } else if (! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { // check for IPs passing through proxy servers // check if multiple IP addresses are set and take the first one $ipAddressList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); foreach ($ipAddressList as $ip) { if ($this->isValidIpAddress($ip)) { $ipAddress = $ip; break; } } } else if (! empty($_SERVER['HTTP_X_FORWARDED']) && $this->isValidIpAddress($_SERVER['HTTP_X_FORWARDED'])) { $ipAddress = $_SERVER['HTTP_X_FORWARDED']; } else if (! empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && $this->isValidIpAddress($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) { $ipAddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP']; } else if (! empty($_SERVER['HTTP_FORWARDED_FOR']) && $this->isValidIpAddress($_SERVER['HTTP_FORWARDED_FOR'])) { $ipAddress = $_SERVER['HTTP_FORWARDED_FOR']; } else if (! empty($_SERVER['HTTP_FORWARDED']) && $this->isValidIpAddress($_SERVER['HTTP_FORWARDED'])) { $ipAddress = $_SERVER['HTTP_FORWARDED']; } else if (! empty($_SERVER['REMOTE_ADDR']) && $this->isValidIpAddress($_SERVER['REMOTE_ADDR'])) { $ipAddress = $_SERVER['REMOTE_ADDR']; } return $ipAddress; } /** * To validate if an IP address is both a valid and does not fall within * a private network range. * * @access public * @param string $ip */ public function isValidIpAddress($ip) { if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) { return false; } return true; } } </pre>
<p>There are many options given all through this article to get the client user’s IP address. This is the best among all the possibilities given, but I highly recommend you to read the section “IP address reliability” below.</p>
<h3>Flowchart to get client user’s IP address</h3>
<p>I have tried my best minimize the flowchart. Please do not look for diagrammatic accuracy. It is just an attempt to present the above PHP script in a flowchart model. But after drawing I realized that the above PHP script is easier to understand than this flowchart ?</p>
<p><img loading="lazy" class="alignnone size-large wp-image-11823" src="https://phppot.com/wp-content/uploads/2020/08/flowchart-get-client-user-ip-address-php-550x475.jpg" alt="flowchart to get client user ip address in php" width="550" height="475" srcset="https://phppot.com/wp-content/uploads/2020/08/flowchart-get-client-user-ip-address-php-550x475.jpg 550w, https://phppot.com/wp-content/uploads/20...00x259.jpg 300w, https://phppot.com/wp-content/uploads/20...68x664.jpg 768w, https://phppot.com/wp-content/uploads/20...ss-php.jpg 1400w" sizes="(max-width: 550px) 100vw, 550px"></p>
<h2>Minimal code to get user’s IP address</h2>
<p>Below one line code will work in most of the situation. Read the ‘IP address reliability’ section below, must. It will give you a good idea.</p>
<pre class="prettyprint lang-php">$ipAddress = $_SERVER['REMOTE_ADDR']?:($_SERVER['HTTP_X_FORWARDED_FOR']?:$_SERVER['HTTP_CLIENT_IP']); </pre>
<h2>Get user’s IP address for CloudFlare hosted websites</h2>
<p>I have taken CloudFlare as example. There are many similar services. You need to talk to that service provider to know which request header they are setting and get the IP address accordingly.</p>
<p>When the website is hosted using CloudFlare service, <code>$_SERVER['REMOTE_ADDR']</code> will return the CloudFlare server’s IP address and not the user’s IP address. So in such a situation, you can make use of the variable set by the CloudFlare server to get the IP address.</p>
<pre class="prettyprint lang-php">if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) { $_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"]; $ipAddress = $_SERVER['REMOTE_ADDR'];
} </pre>
<h2>IP address reliability</h2>
<p><code><a href="https://www.php.net/manual/en/reserved.variables.server.php">$_SERVER</a>['REMOTE_ADDR']</code> is the most reliable variable from the above list of variables. <code>REMOTE_ADDR</code> may not contain the real IP address of the TCP connection as well. It depends on the SAPI configuration.</p>
<p>If the user is behind a proxy server, <code>HTTP_X_FORWARDED_FOR</code> will be set. But this can be easily spoofed by the user by setting an IP address he wishes to expose.</p>
<p>Even the variable <code>X-Forwarded-For</code> or the Client-IP can be set by the user to any value he wishes. So, when you maintain a log of user’s IP address, it is better to store the IP address that is returned by <code>$_SERVER['REMOTE_ADDR']</code> also.</p>
<p>Take an example of a <a href="https://phppot.com/php/simple-php-shopping-cart/">shopping cart</a>. You may display the product price according to the user’s country. In such a scenario, you may use the user’s IP address to determine the user’s country. In such a scenario, the code to get user’s IP address should be fool-proof.</p>
<p>So in summary, if you are building a mission critical application that depends on the user’s IP address, then this is not the way to go. For audit log of the user’s IP address, this may suffice. In essence, understand each line of these PHP code and variables used. Know your use-case well and use it accordingly.</p>
<h2>IP address field length</h2>
<p>When you are storing the IP address in the database, remember to have the field size as 45 for single IP. Because there is a possibility for IPv6 IP addresses. It its full form the IPv6 IP address can be 45 characters in length.</p>
<h2>How to get the IP address of a host</h2>
<p>Using a hostname, we can get the server’s IP address using the PHP’s built-in function <code>gethostbyname</code>. This returns the IPv4 address for the host given in argument.</p>
<pre class="prettyprint lang-php">$ipAddress = gethostbyname('www.example.com');
</pre>
<p>The reverse is possible too by using <code>gethostbyaddr()</code>.</p>
<h2>Client user’s IP address and privacy issues</h2>
<p>Client’s IP address can be considered as private information in certain legislation. It depends on the land of law. Internet is public in general. You never know from which geographic region you will get users.</p>
<p>As per GDPR (Article 4, Point 1; and Recital 49), IP address is a personal data. I would suggest to inform the user and get consent to log the IP address. Also, call it out explicitly in your “Privacy Policy” document.</p>
<p>Explicitly state that you are collecting and logging the client user’s IP address and the reason for doing so.</p>
<h2>Conclusion</h2>
<p>Understand your use-case well. A good understanding of the scenario in which you are going to get and use the client user’s IP address is important. Then understand that the end user can easily spoof his IP address and present you something else. Third understand each line of the code, the server variables, from where the IP address is fetched, who sets it etc. Then decide how it will impact your use-case. Last but not the least, explicitly call out in your privacy policy that you are getting the client user’s IP address and storing it. Also state why you are doing it. As per GDPR, IP address is user’s personal information and so it would be better to get user’s consent before processing it.</p>
<p> <!-- #comments --> </p>
<div class="related-articles">
<h2>Popular Articles</h2>
</p></div>
<p> <a href="https://phppot.com/php/how-to-get-the-client-user-ip-address-in-php/#top" class="top">↑ Back to Top</a> </p>
</div>
https://www.sickgaming.net/blog/2020/08/...ss-in-php/