Reliable API to determine an ip address's city and country
MaxMind has a lite version of their ip2country and ip2city databases: http://www.maxmind.com/app/geolitecity
http://www.maxmind.com/app/geolitecountry
If you don't mind hosting the database yourself, it's free. The paid services are more accurate.
They also provide web services for querying, but it is not free: http://www.maxmind.com/app/web_services#country
Consider using geoplugin, it provides the most information from a single line PHP code, but requires a connection to the geoplugin.com server for every request (and it is free).
Examples :
Json : http://www.geoplugin.net/json.gp?ip=74.125.236.174
{
geoplugin_request: "74.125.236.174",
geoplugin_status: 200,
geoplugin_city: "Mountain View",
geoplugin_region: "CA",
geoplugin_areaCode: "650",
geoplugin_dmaCode: "807",
geoplugin_countryCode: "US",
geoplugin_countryName: "United States",
geoplugin_continentCode: "NA",
geoplugin_latitude: "37.419201",
geoplugin_longitude: "-122.057404",
geoplugin_regionCode: "CA",
geoplugin_regionName: "California",
geoplugin_currencyCode: "USD",
geoplugin_currencySymbol: "$",
geoplugin_currencySymbol_UTF8: "$",
geoplugin_currencyConverter: 1
}
Xml : http://www.geoplugin.net/xml.gp?ip=74.125.236.174
<geoPlugin>
<script/>
<geoplugin_request>74.125.236.174</geoplugin_request>
<geoplugin_status>200</geoplugin_status>
<geoplugin_city>Mountain View</geoplugin_city>
<geoplugin_region>CA</geoplugin_region>
<geoplugin_areaCode>650</geoplugin_areaCode>
<geoplugin_dmaCode>807</geoplugin_dmaCode>
<geoplugin_countryCode>US</geoplugin_countryCode>
<geoplugin_countryName>United States</geoplugin_countryName>
<geoplugin_continentCode>NA</geoplugin_continentCode>
<geoplugin_latitude>37.419201</geoplugin_latitude>
<geoplugin_longitude>-122.057404</geoplugin_longitude>
<geoplugin_regionCode>CA</geoplugin_regionCode>
<geoplugin_regionName>California</geoplugin_regionName>
<geoplugin_currencyCode>USD</geoplugin_currencyCode>
<geoplugin_currencySymbol>$</geoplugin_currencySymbol>
<geoplugin_currencySymbol_UTF8>$</geoplugin_currencySymbol_UTF8>
<geoplugin_currencyConverter>1</geoplugin_currencyConverter>
</geoPlugin>
Other options
http://www.ip2location.com/
Google has free service http://briancray.com/2009/05/29/find-web-visitors-location-javascript-google-api/