Used ipinfo php code snippet, last 7 days stats not populated

Hello, newbie to ipinfo and curl. Have some code based on the ipinfo php code snippet (IP address geolocation in PHP).

Code appears to work identifying country code, however, account stats are not showing any activity.

I suspect the two lines:

    $curl = curl_init($endpoint . $ip); // should it be $curl = curl_init($endpoint . $ip. "?token=".$TOKEN);
    curl_setopt($curl, CURLOPT_USERPWD, "$TOKEN:");

Any help appreciated. Also any advice on better code! :slight_smile: Full code:

// geo location check based on code from https://ipinfo.io/blog/ip-geolocation-in-php/
		
        $ip = '';
        $cc = '';
	$check_cc = 'NZ';
	
        // Set the API endpoint
        $endpoint = "https://ipinfo.io/";
        // Set the IP address
        $ip = empty($_SERVER['REMOTE_ADDR']) ? NULL : $_SERVER['REMOTE_ADDR'];
        // API token via <https://ipinfo.io/signup>
        $token = "removed";

        // Initialize curl session
        $curl = curl_init($endpoint . $ip);
        // Set curl options for token and to return content as string
        curl_setopt($curl, CURLOPT_USERPWD, "$TOKEN:");
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        // Execute the session, making the request
        $response = curl_exec($curl);
        // close cURL session, and free up system resources
        curl_close($curl);

        echo PHP_EOL;
        // Converts JSON string into a PHP object
        $json = json_decode($response, true);
        // get country code details of the API by accessing object properties
        if ( is_array($json) ) {
            $cc = $json['country'];
        }
        
        if ($cc <> $check_cc) {
	    echo "country code: ".$cc. "is not NZ";
        }
        
        // end geo location check
3 Likes

Hey, thank you for posting on the community. I don’t know PHP, but I have reached out to our web team to see if they can assist you.

1 Like

Thanks for sharing with me, @Abdullah.

@competitions I highly recommend utilising our PHP library which handles the complexity of making and parsing HTTP requests, which you can find at github.com/ipinfo/php.

I guess that the issue with your code is not actually with your code, rather you’re running it locally, and therefore the value of $ip is your IP address on your local network (e.g: 192.168.0.0) which is not a “real” IP address that we can geolocate, it’s a Bogon. If you perform a lookup via our API for a bogon, the response will be as follows:

{
  "ip": "192.168.0.0",
  "bogon": true
}

The response does not contain country and therefore your code throws an error. A benefit of our php sdk is that it handles this case for you.

If you’re unable to use our php sdk for some reason then you could update your code to include a fallback for when there is no value for country e.g:

        if ( is_array($json) ) {
-           $cc = $json['country'];
+           $cc = $json['country'] ?? "bogon";
        }

That’ll give you…

country code: bogon is not NZ

There’s quite a few edge cases like this with geolocation, where the expectations you have might not line up with reality, and therefore using an SDK (which has been developed with these edge-cases in mind) will be beneficial. Alternatively, if you’re unable to use the SDK, you can always explore the source code and documentation to get an idea of what sort of behaviour is included. For example, caching is an important feature to minimise the number of requests you make (to prevent a single user from consuming your entire request quota (e.g: if google bot indexes your website, it might make thousands of requests from the same IP)).

Let me know if you need any further insight!

edit: I’ll also add as a general tip when working with third-party APIs, a very valuable debugging tool is inspecting the response body. My first step in debugging your code was to add the following:

+       var_dump($response);
        // Converts JSON string into a PHP object
        $json = json_decode($response, true);

And from there I could see that the response contained bogon: true and didn’t contain country.

2 Likes

Thanks @sam , I was running the code via webserver, so IP address was definitely not local and was calculating country code correctly.

The issue was about the ininfo.io account stats not showing any activity which makes me think I’m not passing the token info correctly.

I’ll have a look at the library, but I’m thinking it might be overkill for a simple id of country.

Another issue I’m trying to wrap my head around is, I found you can also pass for eg:
$curl = curl_init($endpoint . $ip. “/country?token=”.$TOKEN);
yet if I
var_dump($response);
I get
string(3) "AU "
Not sure where that extra space character comes from.

1 Like

@competitions apologies, I misread your post! Variables in php are case sensitive:

-        curl_setopt($curl, CURLOPT_USERPWD, "$TOKEN:");
+        curl_setopt($curl, CURLOPT_USERPWD, $token);

I think that must be a typo in the blog post, @Abdullah is that something you can fix? Thank you :slight_smile:

edit: regarding the /country endpoint – it has a trailing new line which is being converted to a space for some reason. You can pass it through trim e.g:

trim($response);
2 Likes

Thanks @sam and @Abdullah .

Damn variables - always the obvious catches me out. :slight_smile: - stats now appearing!

I had whacked a trim into the code; now deciding which route to go; straight up country or array way. Guess straight up is slightly more efficient, array more standard.

Thanks again for your assistance!

1 Like

I wasn’t involved in the original development of the field endpoints ( /country /city etc.) but looking at the code, I think the new line is intentional for consistent output via command line, as it’s standard for command line output to end with a newline.

For example in Terminal on MacOS, with a new line included, here’s the output:

sam@sam ~ % curl https://ipinfo.io/country
EG
sam@sam ~ % 

However, without a new line, the command line reports that there was a missing new line (with the % character) and the absence of a new line causes the following line to display incorrectly (scroll to the right of this block):

sam@sam ~ % curl https://ipinfo.io/country    
EG%                                                                             sam@sam ~ % 

So in the case of querying our API via the command line, a trailing new line is desirable, because it guarantees that the output is displayed as a single line containing just the field’s value – which is standard, and especially important if you’re scripting via the command line (as all other tools are likely to assume there’ll be a new line).

However, if you’re querying from code, this new-line behaviour isn’t desirable, and you’re much better off receiving the data in a format that is designed for machine parsing: JSON. For that reason, I recommend using the JSON endpoint and parse the JSON to extract the country field – even if it means retrieving a little more data than you need.

1 Like

Great, I had implemented JSON first and was testing country field endpoint, so I’ll leave the code as is, which saves me time anyway!

Thank you for the generous sharing of insight, knowledge and your time.

1 Like

Thank you very much for helping! I really appreciate it. I have fixed the typo and updated the blog post.

2 Likes