Get client IP from PHP

Question:

How can I get the client's real IP address from PHP if possible.

This means that there is a direct connection, or through a proxy , or router or whatever, the real IP of the client computer always identifies me.

Answer:

I will share with you a PHP script that I have created while researching. I use it to know the people who access an Android app that consults data on my server through a URL.

The script shows the following:

  • Client IP
  • Date
  • Country, City or other geographic data of the client, for this it consults an API called Geoplugin. With this API you can determine various geographical elements of the IP.
  • Resource accessed by the client. In my case I wanted to know which part of my API was being accessed. The script retrieves that data and writes it to the file.
  • Write the results to a .txt file. The output of the results can be adapted to your context, that is, file, screen printing, sending by email, etc. that will depend on what you want to do. In this specific case, the data is written to a file, a kind of visit log.

Grades:

  • This is a script with more options than you are asking for, if you just want to get the IP without more, you can ignore the other parts such as using Geoplugin, or obtaining the URL, etc.

  • Geoplugin is an interesting API a free webmaster resource that easily provides geolocation technology …

    It is used to locate the IP and for other things, you can test it online, at the link.

Well now we go to the script. I have commented on some things, in a way that is very easy to understand:

Code:

<?php

    //Llamamos a la función, y ella hace todo :)
    write_visita ();

    //función que escribe la IP del cliente en un archivo de texto    
    function write_visita (){

        //Indicar ruta de archivo válida
        $archivo="ruta/archivo/visitas.txt";

        //Si que quiere ignorar la propia IP escribirla aquí, esto se podría automatizar
        $ip="mi.ip.";
        $new_ip=get_client_ip();

        if ($new_ip!==$ip){
            $now = new DateTime();

       //Distinguir el tipo de petición, 
       // tiene importancia en mi contexto pero no es obligatorio

        if (!$_GET) {
            $datos="*POST: ".$_POST;

        } 
        else
        {
            //Saber a qué URL se accede
            $peticion = explode('/', $_GET['PATH_INFO']);
            $datos=str_pad($peticion[0],10).' '.$peticion[1];   
        }
        $txt =  str_pad($new_ip,25). " ".
                str_pad($now->format('Y-m-d H:i:s'),25)." ".
                str_pad(ip_info($new_ip, "Country"),25)." ".json_encode($datos);

        $myfile = file_put_contents($archivo, $txt.PHP_EOL , FILE_APPEND);
        }
    }


    //Obtiene la IP del cliente
    function get_client_ip() {
        $ipaddress = '';
        if (getenv('HTTP_CLIENT_IP'))
            $ipaddress = getenv('HTTP_CLIENT_IP');
        else if(getenv('HTTP_X_FORWARDED_FOR'))
            $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
        else if(getenv('HTTP_X_FORWARDED'))
            $ipaddress = getenv('HTTP_X_FORWARDED');
        else if(getenv('HTTP_FORWARDED_FOR'))
            $ipaddress = getenv('HTTP_FORWARDED_FOR');
        else if(getenv('HTTP_FORWARDED'))
           $ipaddress = getenv('HTTP_FORWARDED');
        else if(getenv('REMOTE_ADDR'))
            $ipaddress = getenv('REMOTE_ADDR');
        else
            $ipaddress = 'UNKNOWN';
        return $ipaddress;
    }


    //Obtiene la info de la IP del cliente desde geoplugin

    function ip_info($ip = NULL, $purpose = "location", $deep_detect = TRUE) {
        $output = NULL;
        if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
            $ip = $_SERVER["REMOTE_ADDR"];
            if ($deep_detect) {
                if (filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                if (filter_var(@$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_CLIENT_IP'];
            }
        }
        $purpose    = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
        $support    = array("country", "countrycode", "state", "region", "city", "location", "address");
        $continents = array(
            "AF" => "Africa",
            "AN" => "Antarctica",
            "AS" => "Asia",
            "EU" => "Europe",
            "OC" => "Australia (Oceania)",
            "NA" => "North America",
            "SA" => "South America"
        );
        if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support)) {
            $ipdat = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
            if (@strlen(trim($ipdat->geoplugin_countryCode)) == 2) {
                switch ($purpose) {
                    case "location":
                        $output = array(
                            "city"           => @$ipdat->geoplugin_city,
                            "state"          => @$ipdat->geoplugin_regionName,
                            "country"        => @$ipdat->geoplugin_countryName,
                            "country_code"   => @$ipdat->geoplugin_countryCode,
                            "continent"      => @$continents[strtoupper($ipdat->geoplugin_continentCode)],
                            "continent_code" => @$ipdat->geoplugin_continentCode
                        );
                        break;
                    case "address":
                        $address = array($ipdat->geoplugin_countryName);
                        if (@strlen($ipdat->geoplugin_regionName) >= 1)
                            $address[] = $ipdat->geoplugin_regionName;
                        if (@strlen($ipdat->geoplugin_city) >= 1)
                            $address[] = $ipdat->geoplugin_city;
                        $output = implode(", ", array_reverse($address));
                        break;
                    case "city":
                        $output = @$ipdat->geoplugin_city;
                        break;
                    case "state":
                        $output = @$ipdat->geoplugin_regionName;
                        break;
                    case "region":
                        $output = @$ipdat->geoplugin_regionName;
                        break;
                    case "country":
                        $output = @$ipdat->geoplugin_countryName;
                        break;
                    case "countrycode":
                        $output = @$ipdat->geoplugin_countryCode;
                        break;
                }
            }
        }
        return $output;
    }

?>

Result

Part of the data written to the file:

82.24.244.140             2017-05-02 03:43:10       United Kingdom            "laudes     20170502"
89.141.58.49              2017-05-02 04:03:38       Spain                     "oficio     20170502"
80.58.131.161             2017-05-02 05:37:46       Spain                     "oficio     20170502"
186.119.11.69             2017-05-02 06:00:42       Colombia                  "laudes     20170502"
186.119.11.69             2017-05-02 06:03:17       Colombia                  "visperas   20170502"
137.101.114.197           2017-05-02 06:30:34       Spain                     "tercia     20170502"
189.163.204.25            2017-05-02 07:00:40       Mexico                    "homilias   20170502"
179.40.81.2               2017-05-02 07:06:03       Argentina                 "oficio     20170502"
176.83.200.79             2017-05-02 07:23:57       Spain                     "laudes     20170502"
190.102.58.34             2017-05-02 07:45:20       Panama                    "homilias   20170502"
170.51.58.170             2017-05-02 08:00:28       Paraguay                  "tercia     20170502"
187.134.245.128           2017-05-02 08:42:29       Mexico                    "laudes     20170502"
83.32.169.72              2017-05-02 11:48:40       Spain                     "visperas   20170502"
Scroll to Top