PHP & API for IP Geolocation - php

I am trying to use http://www.hostip.info/use.html in my web app to show the approximate City location of an IP address. I cannot figure out how to actually show the contents of the API... Here is what I have that is not working.
function showCity($currIP){
$lookupData = 'http://api.hostip.info/get_html.php?ip='.$currIP;
return $lookupData;
}

Your API returns this:
Country: UNITED STATES (US)
City: Seattle, WA
IP: 168.111.127.225
So you need to do some string parsing on that result. Using the below will get your started:
$array = preg_split('/$\R?^:/m', $lookupData);
print_r($array);
Try this instead:
$array = preg_split("/[\r\n]/", $lookupData, -1, PREG_SPLIT_NO_EMPTY);
Also, as was mentioned by mcmajkel, if you use the JSON api link, you can get to it with this:
$lookupData = 'http://api.hostip.info/get_json.php?ip='.$currIP;
$api = json_decode($lookupData);
$myName = $api->country_name;
$myCode = $api->country_code;
$myCity = $api->city;
$myIP = $api->ip;

This call returns string, as mentioned by GregP. But you can call
http://api.hostip.info/get_json.php?ip=12.215.42.19
And get a nice piece of JSON in return, which will be easier to
parse

Related

My code for downloading longitude and latitude is now returning null value for existing areas

I have a code for downloading longitude and latitude coordinates from google maps, it was working before but now it's returning null value. Below is my code;
<?php
//Optaining Latitude and Longitude
$address = $title;
$url = file_get_contents("http://maps.google.com/maps/api/geocode/json?address=".urlencode($address)."&sensor=false");
$response = json_decode($url);
$latitudee = "";
$longitudee = "";
if ($response->status == 'OK') {
$latitudee = $response->results[0]->geometry->location->lat;
$longitudee = $response->results[0]->geometry->location->lng;
}
echo $latitudee;
?>
Google now requires you to include API key for calling geocode API. Change the 'url' variable as follows-
$url = file_get_contents("http://maps.google.com/maps/api/geocode/json?address=".urlencode($address)."&key=YOUR_API_KEY");
The sensor parameter is no longer required to pass as per google developer guide
https://developers.google.com/maps/documentation/geocoding/intro
If you don't have an API key, you can get it here-
https://developers.google.com/maps/documentation/javascript/get-api-key
Also don't forget to restrict your key once you have one.
Returned error message states what is the problem here:
Keyless access to Google Maps Platform is deprecated.
Please use an API key with all your API calls to avoid service interruption.
For further details please refer to http://g.co/dev/maps-no-account
After recent changes to google maps, you will need to create an account to use google maps API, this will generate an API key and you have to append it to URL that you use
"http://maps.google.com/maps/api/geocode/json?address=".urlencode($address)."&key=YOUR_API_KEY"
you must Formatted your address:
$formattedAddr = str_replace(' ','+',$address);
Send request and receive json data by address:
$geocodeFromAddr = file_get_contents('http://maps.googleapis.com/maps/api/geocode/json?address='.$formattedAddr.'&sensor=false');
$output = json_decode($geocodeFromAddr);
Get latitude and longitute from json data:
if ($output->status == 'OK') {
$data['latitude'] = $output->results[0]->geometry->location->lat;
$data['longitude'] = $output->results[0]->geometry->location->lng;
}
I was able to find where the problem was, Google changed the API url to the one below;
$url = file_get_contents("https://maps.googleapis.com/maps/api/geocode/json?address=".urlencode($add`enter code here`ress)."&key=YOUR_API_KEY");

How to use Nominatim API through PHP to retrieve latitude and longitude?

Below is the code that I am currently using in which I pass an address to the function and the Nominatim API should return a JSON from which I could retrieve the latitude and longitude of the address from.
function geocode($address){
// url encode the address
$address = urlencode($address);
$url = 'http://nominatim.openstreetmap.org/?format=json&addressdetails=1&q={$address}&format=json&limit=1';
// get the json response
$resp_json = file_get_contents($url);
// decode the json
$resp = json_decode($resp_json, true);
// get the important data
$lati = $resp['lat'];
$longi = $resp['lon'];
// put the data in the array
$data_arr = array();
array_push(
$data_arr,
$lati,
$longi
);
return $data_arr;
}
The problem with it is that I always end up with an Internal Server Error. I have checked the Logs and this constantly gets repeated:
[[DATE] America/New_York] PHP Notice: Undefined index: title in [...php] on line [...]
[[DATE] America/New_York] PHP Notice: Undefined variable: area in [...php] on line [...]
What could be the issue here? Is it because of the _ in New_York? I have tried using str_replace to swap that with a + but that doesn't seem to work and the same error is still returned.
Also, the URL works fine since I have tested it out through JavaScript and manually (though {$address} was replaced with an actual address).
Would really appreciate any help with this, thank you!
Edit
This has now been fixed. The problem seems to be with Nominatim not being able to pickup certain values and so returns an error as a result
The errors you have mentioned don't appear to relate to the code you posted given the variables title and area are not present. I can provide some help for the geocode function you posted.
The main issue is that there are single quotes around the $url string - this means that $address is not injected into the string and the requests is for the lat/long of "$address". Using double quotes resolves this issue:
$url = "http://nominatim.openstreetmap.org/?format=json&addressdetails=1&q={$address}&format=json&limit=1";
Secondly, the response contains an array of arrays (if were not for the limit parameter more than one result might be expected). So when fetch the details out of the response, look in $resp[0] rather than just $resp.
// get the important data
$lati = $resp[0]['lat'];
$longi = $resp[0]['lon'];
In full, with some abbreviation of the array building at the end for simplicity:
function geocode($address){
// url encode the address
$address = urlencode($address);
$url = "http://nominatim.openstreetmap.org/?format=json&addressdetails=1&q={$address}&format=json&limit=1";
// get the json response
$resp_json = file_get_contents($url);
// decode the json
$resp = json_decode($resp_json, true);
return array($resp[0]['lat'], $resp[0]['lon']);
}
Once you are happy it works, I'd recommend adding in some error handling for both the http request and decoding/returning of the response.

Ip location finder

I want to find the location (country, city,..) of my site visitor by their IP.
I'm coding php.
who can help me?
something like this:
$url = json_decode(file_get_contents("http://api.ipinfodb.com/v3/ip-city/?key=/*userapikey*/
ip=".$_SERVER['REMOTE_ADDR']."&format=json"));
$country=$url->countryName; // user country
$city=$url->cityName; // city
$region=$url->regionName; // regoin
$latitude=$url->latitude; //lat and lon
$longitude=$url->longitude;
Seems there is a & missing in the URL:
$url = json_decode(file_get_contents("http://api.ipinfodb.com/v3/ip-city/?key=/*userapikey*/&ip=".$_SERVER['REMOTE_ADDR']."&format=json"));
Probably, you should encode the IP:
$url = json_decode(file_get_contents("http://api.ipinfodb.com/v3/ip-city/?key=/*userapikey*/&ip=".urlencode($_SERVER['REMOTE_ADDR'])."&format=json"));
Then you can do this to get information about the result:
var_dump($url);
If you have another problem, please write it to the question.
Have a look at freegeoip.net. It's a webservice that gives you exactly the data you need for a specific IP.
E.g.:
https://freegeoip.net/json/1.2.3.4
will give you this JSON data:
{
ip: "1.2.3.4",
country_code: "US",
country_name: "USA",
region_code: "WA",
region_name: "Washington",
city: "Mukilteo",
zip_code: "98275",
time_zone: "America/Los_Angeles",
latitude: 47.945,
longitude: -122.305,
metro_code: 819
}
Check out https://freegeoip.net/. They offer a free API for up to 10,000 searches per hour.
Example:
$res = json_decode(file_get_contents("https://freegeoip.net/json/109.80.75.20"));
$countryCode = $res->country_code;
$country = $res->country_name;

Getting currency conversion data from Yahooapis now that iGoogle is gone

Up until yesterday I had a perfectly working budget organizer site/app working with iGoogle.
Through PHP, using the following little line
file_get_contents('http://www.google.com/ig/calculator?hl=en&q=1usd=?eur');
and similar I was able to get all I needed.
As of today, this is no longer working. When I looked into the issue, what has happened is that Google has retired iGoogle. Bummer!
Anyway, I was looking around elsewhere but I can't find anything that fits my needs. I would REALLY love to just fix it and get it running again by just switching this one line of code (i.e. changing the Google address with the address of some other currency API available) but it seems like none does.
The API from rate-exchange.appspot.com seems like it could be a iGoogle analog but, alas, it never works. I keep getting an "Over Quota" message.
(Here comes an initial question: anybody out there know of a simple, reliable, iGoogle-sort API?)
So I guess the natural thing would be to the Yahoo YQL feature (at least I suppose it is as reliable).
Yahoo's queries look like this:
http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.xchange where pair in ("USDEUR", "USDJPY", "USDBGN")&env=store://datatables.org/alltableswithkeys
What I really can't figure out is how to parse this data. It outputs an XML.
What I used to have is this:
function exchange($inputAmount,$inputCurrency,$outputCurrency) {
$exchange = file_get_contents('http://www.google.com/ig/calculator?hl=en&q='.$inputAmount.$inputCurrency.'=?'.$outputCurrency);
$exchange = explode('"', $exchange);
$exchange = explode('.', $exchange['3']);
$exchange[0] = str_replace(" ", "",preg_replace('/\D/', '', $exchange[0]));
if(isset($exchange[1])){
$exchange[1] = str_replace(" ", "",preg_replace('/\D/', '', $exchange[1]));
$exchange = $exchange[0].".".$exchange[1];
} else{
$exchange = $exchange[0];
}
return $exchange;
}
So the user was able to get the exchange rate from an input currency such as "USD" and an output currency such as "EUR" on a specific amount of money. As I said, this was working swimmingly up until yesterday night.
Any ideas?
Never mind! Solved it!
For anyone interested, here's what I did to get my code to work (with the least chnges possible) with the Yahoo YQL:
// ** GET EXCHANGE INFO FROM YAHOO YQL ** //
$url = 'http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.xchange where pair in ("USDEUR", "EURUSD")&env=store://datatables.org/alltableswithkeys'; //<-- Get the YQL info from Yahoo (here I'm only interested in converting from USD to EUR and vice-versa; you should add all conversion pairs you need).
$xml = simplexml_load_file($url) or die("Exchange feed not loading!"); //<-- Load the XML file into PHP variable.
$exchange = array(); //<-- Build an array to hold the data we need.
for($i=0; $i<2; $i++): //<-- For loop to get data specific to each exchange pair (you should change 2 to the actual amount of pairs you're querying for).
$name = (string)$xml->results->rate[$i]->Name; //<-- Get the name of the pair and turn it into a string (this looks like this: "USD to EUR").
$rate = (string)$xml->results->rate[$i]->Rate; //<-- Do the same for the actual rate resulting from the conversion.
$exchange[$name] = $rate; //<-- Put the data pairs into the array.
endfor; //<-- End for loop. :)
// ** WORK WITH EXCHANGE INFO ** //
$toeur = array( //<-- Create new array specific for conversion to one of the units needed.
'usd' => $exchange['USD to EUR'], //<-- Create an array key for each unit used. In this case, in order to get the conversion of USD to EUR I ask for it from my $exchange array with the pair Name.
'eur' => 1); //<-- The way I coded the app, I found it more practical to also create a conversion for the unit into itself and simply use a 1, which translates into "do not convert"
$tousd = array(
'eur' => $exchange['EUR to USD'],
'usd' => 1);
This is basically all you need to get all the exchange info you want. After that, you use it all something like this:
amount*$toxxx['coin'];
So, say I wanted to know how many Euro is 100 USD right now:
100*$toeur['usd'];
Piece of cake!
Still a very useful solution by QuestionerNo27. Since early 2015, however, Yahoo YQL apparently slightly changed the XML output of their api. 'Name' now no longer translates into a string like 'USD to EUR', but to 'USD/EUR' and should in the code above be referenced this way:
$toeur = array(
'usd' => $exchange['USD/EUR']
instead of
$toeur = array(
'usd' => $exchange['USD to EUR']
and in a similar fashion for other currency conversions.
I created a routine to convert the currency based on #QuestionerNo27 http://jamhubsoftware.com/geoip/currencyconvertor.php?fromcur=USD&tocur=EUR&amount=1 you can consume this
<?php
$fromcur = $_GET['fromcur'];
$tocur = $_GET['tocur'];
$amt = $_GET['amount'];
// ** GET EXCHANGE INFO FROM YAHOO YQL ** //
$url = 'http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.xchange where pair in ("'.$fromcur.$tocur.'")&env=store://datatables.org/alltableswithkeys'; //<-- Get the YQL info from Yahoo (here I'm only interested in converting from USD to EUR and vice-versa; you should add all conversion pairs you need).
$xml = simplexml_load_file($url) or die("Exchange feed not loading!"); //<-- Load the XML file into PHP variable.
$exchange = array(); //<-- Build an array to hold the data we need.
for($i=0; $i<2; $i++): //<-- For loop to get data specific to each exchange pair (you should change 2 to the actual amount of pairs you're querying for).
$name = (string)$xml->results->rate[$i]->Name; //<-- Get the name of the pair and turn it into a string (this looks like this: "USD to EUR").
$rate = (string)$xml->results->rate[$i]->Rate; //<-- Do the same for the actual rate resulting from the conversion.
$exchange[$name] = $rate; //<-- Put the data pairs into the array.
endfor; //<-- End for loop. :)
// ** WORK WITH EXCHANGE INFO ** //
$conv = $fromcur . '/' . $tocur;
$toeur = array( //<-- Create new array specific for conversion to one of the units needed.
$tocur => $amt*$exchange[$conv], //<-- Create an array key for each unit used. In this case, in order to get the conversion of USD to EUR I ask for it from my $exchange array with the pair Name.
$fromcur => $amt,
"ex_amt" =>$amt*$exchange[$conv]); //<-- The way I coded the app, I found it more practical to also create a conversion for the unit into itself and simply use a 1, which translates into "do not convert"
echo json_encode($toeur);
?>

Convert Address to Latitude/longitude (using php)

I want to parse this URL with PHP to get the latitude of a specific address (2+bis+avenue+Foch75116+Paris+FR):
I use the google maps web service: http://maps.googleapis.com/maps/api/geocode/json?address=2+bis+avenue+Foch75116+Paris+FR&sensor=false
// Get the JSON
$url='http://maps.googleapis.com/maps/api/geocode/json?address=2+bis+avenue+Foch75116+Paris+FR&sensor=false';
$source = file_get_contents($url);
$obj = json_decode($source);
var_dump($obj);
It doesn't work. I have this error :
OVER_QUERY_LIMIT
So I searched on the web and I found that there is a limitation using google maps api (Min 1 sec between 2 queries and max 2500 queries per day)
Do you know any way to convert an adress to --> Latitude/Longitude ???
You are accessing results incorrectly.
// Get the JSON
$url='http://maps.googleapis.com/maps/api/geocode/json?address=2+bis+avenue+Foch75116+Paris+FR&sensor=false';
$source = file_get_contents($url);
$obj = json_decode($source);
$LATITUDE = $obj->results[0]->geometry->location->lat;
echo $LATITUDE;

Categories