tomccabe Posted May 26, 2010 Share Posted May 26, 2010 I have to write a script for some banners that need to be returned the user's zip code...anyone have any idea how to do this? :'( Quote Link to comment Share on other sites More sharing options...
teamatomic Posted May 27, 2010 Share Posted May 27, 2010 Unless the user logs in and you have his city(some cities have multiple zips) you are out of luck. You can get close to their city with something like geolitecities but all you can get is the city that the ISP has for the IP, which can get to close as the local office most times. HTH Teamatomic Quote Link to comment Share on other sites More sharing options...
tomccabe Posted May 28, 2010 Author Share Posted May 28, 2010 Hey HTH, This was great...gives me *almost* what I need. I've got it looking up city/state at this point, but their database doesn't actually have zip codes. They explain this as such: About 56% of GeoIP City records in the United States have postal codes. In many cases we are able to identify the city, but the city has multiple postal codes, so we don't identify the postal code in that case unless we are confident that the IP address is likely to be in that postal code and not one of the others in the city. Not being able to determine the postal code in many cases is a general limitation of geolocation services. Typically an ISP will have its users connect to a central office and assign their client an IP address from a block of IP address. The block of IP addresses will be given out to clients spanning several zip codes. For instance, if you connect to a dial-up ISP in New York City, your provider will typically have a 212 access number number that is used from any postal code in the city. With a postal code database such as iBegin.com's free US Zip Codes you could lookup a US postal code using the city and state returned by the GeoIP City database. Alternatively you can use the GEO-132 Binary Format (without metro/area codes) GeoIP City, which contains postal codes for every US city-level resolution, even when we aren't confident in the accuracy of the postal code. For the CSV format, we have a location file with postal codes for every US city record. The site this points to has a great csv file with zip codes that is totally fine (weather difference won't be that crazy if I'm off by 25 miles...it doesn't need to be a scientific match). Throughout searching I've vaguely gotten the idea that you can run an SQL query on a csv file (maybe I'm getting that wrong). I do know you can import one into an SQL database, but as this will be an advertisement the server won't necessarily have SQL installed. What are my options? I'm so close I just need to figure out how to interface these 2 pieces of data! Arrrghhhh!!! Quote Link to comment Share on other sites More sharing options...
tomccabe Posted May 28, 2010 Author Share Posted May 28, 2010 After a bit more digging I found the fgetcsv() function. Seems to be what I'm after. Here's the steps I think this needs to take: 1. Run ip search on geoip database. 2. if {find match with zip} return zip -task complete in this case 3. else {take lat/long from geoip. Run csv query on csv file. Check each entry's lat/long. Get sum of abs value of difference between lats and abs value of difference between long. Return zip from record with lowest total difference. The portions in bold which specifically deal with the csv records is where I'm stumped. The examples in the php manual are not all that helpful for my situation. Quote Link to comment Share on other sites More sharing options...
pornophobic Posted May 28, 2010 Share Posted May 28, 2010 I don't want to throw confusion in here, but it's worth noting that to reduce the time of results maxmind provides .dat files which are much, much faster with turning up results. I have, and am currently using geolitecity to to IP location and the .dat file loads significantly faster than storing all the values in a database. I think the query time for a city database compared to the query time with the .dat is a difference of about ~=1 second. Which is quite a bit when it comes to queries. Quote Link to comment Share on other sites More sharing options...
tomccabe Posted May 28, 2010 Author Share Posted May 28, 2010 Yeah, porno, you are absolutely correct. Unfortunately this banner is one that will display the weather at the user's location and that API needs zip code data, not simply city. I had no problem getting the city data as soon as HTH pointed me to GeoCity. The problem is that they only have zip codes for about half their records. Not too helpful a majority of the time (for instance no zip for me in Hollywood or partner doing the Flash portion in NYC). That said, I did solve my problem and will post my solution for anyone else that might come across this here or through Google (and feel free to tell me if it could be more efficient! I'm sure there are ways I might cut down on query time of the CSV). I did indeed do it by latitude and longitude and used the CSV file with zip codes/lat/lon located here (as suggested by GeoCity FAQ): http://geocoder.ibegin.com/downloads.php The script cuts out before using the CSV if the IP has a zip code record in the GeoCity database, so it only adds the query time if it absolutely needs to (and it is about a full second). <?php include("geoipcity.inc"); include("geoipregionvars.php"); // OPEN GEOCITY DATABASE $gi = geoip_open("GeoLiteCity.dat",GEOIP_STANDARD); // IP CHECKS if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip=$_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip=$_SERVER['HTTP_X_FORWARDED_FOR']; } else { $ip=$_SERVER['REMOTE_ADDR']; } // GET GEOCITY LOCATION DATA FROM IP $record = geoip_record_by_addr($gi,$ip); // IF ZIP IS LOCATED IN GEOCITY DATABASE, RETURN if ($record->postal_code) { return $record->postal_code; } // IF NOT RESOLVE ZIP CODE BY LATITUDE/LONGITUDE & RETURN else { $lat = $record->latitude; // save GeoCity latitude $lon = $record->longitude; // save GeoCity longitude $row = 0; // start at first row of zip code file $diff = 10; // init out of bounds difference $open = fopen("zips.csv", "r"); // open zip code file while (($data = fgetcsv($open, 1000, ",")) !== FALSE) { // check records $test = abs($data[3] - $lat) + abs($data[4] - $lon); // get total difference between this record and actual lat/lon if (($test < 10) && ($test < $diff)) { // if it's reasonably close and less than the current lowest $diff = $test; // reset lowest record $zip = $data[0]; // set this zip as current } } return $zip; } // IF NO RESULT FROM EITHER, RETURN NYC DEFAULT if ($zip == NULL) { $default = "10001"; return $default; } geoip_close($gi); ?> Quote Link to comment Share on other sites More sharing options...
pornophobic Posted May 28, 2010 Share Posted May 28, 2010 Well... Since you are only using it to get a zip code... I think I may have a solution to your problem since my curiosity is peaked concerning if what I'm working on will work or not since I could use it in some of my projects as well. If it does, today may be your lucky day and I will share it! Quote Link to comment Share on other sites More sharing options...
tomccabe Posted May 28, 2010 Author Share Posted May 28, 2010 I set the first condition of the while loop for a state matching the GeoCity state (the only other field they share) and that's shaved a little bit of time off (getting about 3500 - 5500ms on firebug now), but now my interest is also peaked! This stupid banner is actually turning into a fun little project haha. Quote Link to comment Share on other sites More sharing options...
teamatomic Posted May 28, 2010 Share Posted May 28, 2010 If you want it I have a set of folders for the states with folders for all cities that has an info.txt file with county|lat|long|zip I use for 7 day forecasts(which require lat|long as per the NWS soap server). HTH Teamatomic Quote Link to comment Share on other sites More sharing options...
ThisisForReal Posted May 28, 2010 Share Posted May 28, 2010 The free IP address geolocation SQL databases from ipinfodb have some step by step guides and a decent forum/tutorial on how to use it, if that helps. http://ipinfodb.com/ip_database.php Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.