Whenever you’re building a site that has a directory of businesses or people or anything with a physical location, it commonly lends itself to offering a search form which allows the user to search by distance from a given location.
For example, a national or state-wide company with many branches may want to allow their website visitors to find a location near them. Or perhaps you may be building a directory of specialist doctors, or a site with real estate listings, and want to offer users the ability to search within X miles from a given location. It sounds like a difficult feature to implement but in reality it is not.
The solution comes in essentially three parts, a zip code database, your database of items/people/businesses, and a small PHP script. The database is list of city, state, and county information that is linked to latitude and longitude information, which allows the script to determine where zip codes are in relationship to one another. A flexible class is provided to allow simple access to the zip code functions.
This article does assume that you have a basic understanding of working with PHP and MySQL. Make sure to download the zip archive containing the database and associated scripts before getting started.
You’ll find 6 SQL files in the /sql directory of the zip file that you must also run in order to load the zip code database into MySQL. Make sure to run create_table.sql first in order to create the zip code database table before loading in its entries, which have been split up into data_1.sql, data_2.sql and so on. The zip code database contains over 40,000 rows so it has been split up into 5 parts to allow importing from a web browser via phpMyAdmin’s “Import” tab.
Additionally, we will need a database of things to search for, so we’ll use a database of properties that might be for sale as an example. Below is some very basic SQL for our properties table:
CREATE TABLE `properties` ( `id` int(11) unsigned NOT NULL auto_increment, `zip_code` varchar(5) collate utf8_bin NOT NULL, `address` varchar(50) collate utf8_bin default NULL, `seller_name` varchar(50) collate utf8_bin default NULL, PRIMARY KEY (`id`), KEY `zip_code` (`zip_code`) )
The key field in the table above is zip_code, as you can imagine, the other fields could really be anything that might be associated with a zip code. After creating our table, add some records to it.
For the purposes of this post we’ll use a simple zipcode field to search, as reviewing the details of creating a teired city, state, zip selection fieldset warrants a post of its own. So we might have a search field on our search.htm page that looks like this:
![]()
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Zip Code Search</title> </head> <body> <form method="post" action="results.php"> <label for="miles">Search within </label> <input type="text" name="miles" id="miles" size="10" /> miles of <label for="zip_code"></label> <input type="text" name="zip_code" id="zip_code" /> <input type="submit" name="submit" value="Search" /> </form> </body> </html>
Now that we have both of our database tables setup, and our search form, we must create the results.php script to process our form submission and generate a result (find the items within X miles of a given zip code!) The full source code is below:
require_once('zipcode.class.php');
mysql_connect('host','username','password') or die(mysql_error());
mysql_select_db('database_name') or die(mysql_error());
$z = new zipcode_class;
$zips = $z->get_zips_in_range($_POST['zip_code'], $_POST['miles'], _ZIPS_SORT_BY_DISTANCE_ASC, true);
if ($zips === false) {
echo 'Error: '.$z->last_error;
} else {
$zips_in_range = implode(',', array_keys($zips) );
}
$result = mysql_query("SELECT * FROM properties WHERE zip_code IN (". $zips_in_range . ")");
while ($row = mysql_fetch_assoc($result) ) {
print_r($row);
}
Let’s go through the above script line by line and review what is happening.
Obviously this is a bare bones example but I hope that I have illustrated one way of using a great script to accomplish a very useful task on your websites; I am sure it will come in handy time and time again. There are obviously some poor programming practices being illustrated above for the sake of brevity, such as using raw POST data in a function without sanitizing it first, and I hope you will take these things into consideration as you build out your website. The zipcode class that was used in this example was created by Micah Carrick, and actually contains a whole host of other nice features such as calculating the distance between two coordinates, calculating the distance between two zip codes, and returning information about a given zip code. I’ve included my additional search.htm and results.php files, which are detailed above for you to experiment with in addition to the provided demo.php originally included in the archive. If you have any questions about specific implementations or modifying the techniques covered above, please comment below.
Download zipcode-1.2.0.zip [1MB]