Using Google Maps, Geocoding and PHP to find the distance between UK Postcodes

If you’re looking to make any kind of radius checker, delivery calculator etc, you will need to have some method of calculating this distance. Unfortunately for us in the UK, Royal Mail keep a tight grip on postcode data.

As a result, the best low-budget way of finding postcodes is by using the Google Maps api – which in itself isn’t 100% accurate (but good enough).

So we can use the following code:

<?php
// Specify Postcodes to Geocode
$postcode1 = 'BH151DA';
$postcode2 = 'BH213AP';

// Geocode Postcodes & Get Co-ordinates 1st Postcode
$pc1 = 'http://maps.google.com/maps/geo?q='.$postcode1.',+UK&output=csv&sensor=false';
$data1 = @file_get_contents($pc1);
$result1 = explode(",", $data1);
$custlat1 = $result1[2];
$custlong1 = $result1[3];

// Geocode Postcodes & Get Co-ordinates 2nd Postcode
$pc2 = 'http://maps.google.com/maps/geo?q='.$postcode2.',+UK&output=csv&sensor=false';
$data2 = @file_get_contents($pc2);
$result2 = explode(",", $data2);
$custlat2 = $result2[2];
$custlong2 = $result2[3];

// Work out the distance!
$pi80 = M_PI / 180;
$custlat1 *= $pi80;
$custlong1 *= $pi80;
$custlat2 *= $pi80;
$custlong2 *= $pi80;

$r = 6372.797; // mean radius of Earth in km
$dlat = $custlat2 - $custlat1;
$dlng = $custlong2 - $custlong1;
$a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2);
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));

// Distance in KM
$km = round($r * $c, 2);

// Distance in Miles
$miles = round($km * 0.621371192, 2);

echo 'The distance between '.$postcode1.' and '.$postcode2.' is '.$km.'Km ('.$miles.' miles).';

?>

You could use $result1[0] and $result2[0] to check codes. If the value is anything other than 200 the postcode is invalid. Also note UK is also searched for to guarantee correct results!

The result is also rounded to make sure we only have 2 decimal places. Make sure your postcodes do not have any spaces in when they go to Google, if you’re collecting them from a form maybe use:

function nowhitespace($data) {
return preg_replace('/\s/', '', $data);
}
$postcode1 = nowhitespace($postcode1);

to remove all spaces before processing, and the following to check it’s ok after processing:

if (($result1[0] != 200) || ($result2[0] != 200)) {
echo "<p>Invalid Postcode(s) Entered. Please try again.</p>";
} else {

Good luck!

Posted in Coding | Tagged , , , , | Leave a comment

Vertical Align and Centering Images in Div tags

Just thought I’d share my preferred solution for vertical aligning an image within a Div.

You can’t use <p> tags, text align, vertical align or even image align as this messes up the display? I had this problem with thumbnails or varying sizes which needed to be centered in a div of specific size.

Using the approach suggested here and classing it as a table cell wasn’t great as it messed up the display…so I just set the image as a background which you can center & put a transparent gif over it to link to. Not ideal but it works!

<div style="background-image: url('thumbnail.gif');  background-repeat: no-repeat; background-position: center; width: 100px;  height: 100px">
<a href="page.php">
<img src="transparent  gif" width="100" height="100" />
</a>
</div>

You could also consider using absolute div tags but that also tends to interfere with surrounding design elements! Other solutions welcome!

Posted in Coding | Tagged , , | Leave a comment

Resubmitting forms upon page refresh or reload in PHP

A common problem with forms is the annoying resubmit when the user reloads or refreshes a page. This can result in duplicate database records if not dealt with properly.

There are a number of simple solutions to this problem, I’ll go through a couple below.

1. Use two files (one with the form on and one to process), and redirect back to the first page when the processing is done.

Here’s some sample code for the form page (form.htm):

<form name="form1" method="post" action="process.php">
<input type="text" name="text" id="text">
<input type="submit" name="submit" id="submit" value="Submit">
</form>

and here’s some sample code for the processing page (process.php):

<?php
if (isset($_POST['submit'])) {
$text = $_POST['text'];
$query = mysql_query("Insert into our database etc");
header("Location: form.htm");
}
?>

This uses PHP header to redirect the user back to the form page when the form is processed, or if the user directly visits process.php without the form submission. Bear in mind this is only example code and so is not complete or secure.

2. Use two files (one with the form on and to process and one when finished), redirecting to the second page when finished.

Here is some sample code for the process/form page (form.php):

<?php
if (isset($_POST['submit'])) {
$text = $_POST['text'];
$query = mysql_query("Insert into our database etc");
}
header("Location: thanks.htm");
?>
<form name="form1" method="post" action="form.php">
<input type="text" name="text" id="text">
<input type="submit" name="submit" id="submit" value="Submit">
</form>

and here’s the code for the final page (thanks.htm):

<p>Thanks for filling out our form!</p>

The user can still refresh the final page as much as they want as the processing was done elsewhere.

3. Use one file, doing all the processing and then displaying a thank you message.

This uses a $_GET to tell the script we’ve finished and display a message (form.php):

<?php
if ($_GET['success']) {
echo "Your text was saved successfully!";
} elseif (isset($_POST['submit'])) {
$text = $_POST['text'];
$query = mysql_query("Insert into our database etc");
header("Location: form.php?success=1");
}
?>
<form name="form1" method="post" action="form.php">
<input type="text" name="text" id="text">
<input type="submit" name="submit" id="submit" value="Submit">
</form>

I suppose you could change the echo to a die if you didn’t want to show the form, or add in a final else like this:

<?php
if ($_GET['success']) {
echo "Your text was saved successfully!";
} elseif (isset($_POST['submit'])) {
$text = $_POST['text'];
$query = mysql_query("Insert into our database etc");
header("Location: form.php?success=1");
} else {
?>
<form name="form1" method="post" action="form.php">
<input type="text" name="text" id="text">
<input type="submit" name="submit" id="submit" value="Submit">
</form>
<?php } ?>

so that the form would not be displayed when the Success text was.

4. Involve sessions

You could also involve sessions in your form by storing the POST variables in a session before processing, eg:

$_SESSION['postdata'] = $_POST;

and clearing the session once the processing had been done, eg:

unset($_SESSION['postdata'])

You could also enter a timestamp with each posted form and store this in a database, checking before processing for identical timestamps, it depends on the nature of your application and your personal preference.

Any comments/improvements welcome!

Posted in Coding | Tagged , , | Leave a comment

Mediatemple Grid Server (gs) MySQL and Support Problems

Let me be honest, I really REALLY want to like Mediatemple. Their website is extremely well designed, there’s loads of support information in their customer area, their GPU system gives you detailed information on high-resource scripts and files on your server and their file system has excellent uptime and good speeds.

Mediatemple GS Control Panel

However, as I write this one of our personal projects which we put on it’s own Mediatemple server is displaying a MySQL connection error – again. Over the last week it’s been a constant on/off battle made many times worse by the very slow Mediatemple support.

Mediatemple Sport a Speedy 20Hr Response Time

It was acceptable to begin with, 5 hours for the first reply, 13 hours for the second that informed me there was a bigger issue (mediatemple always seem to have MySQL issues), 7 hours later they informed me the issue had been fixed.

25 hours later (yes, TWENTY FIVE), after I had replied saying there was still a problem, they told me it was all running ok…which it was THEN but it had been too slow to work for hours before they replied.

I should probably point out that all of this was mid-week so the only reason I can see for the slow responses is that everyone was busy working on the problem?

Mediatemple Support Home

In the past I have had timely replies to my tickets (2 hour average) which is not as good as some (VPSLatch and PowerVPS being the best I’ve seen) but decent. In fact the response time is estimated at 4 hours 28 mins in the control panel right now. I have had only one instance of downtime for my files but unfortunately there are a couple of other shortcomings of their system including overly complicated domain setup (for subdomains) and how they work with the system. Whereas cPanel (for example) has seperate stats and settings for each domain, Mediatemple’s control panel mixes them together so the Urchin stats show all sites as one.

This post isn’t completely one sided, as the amount of space & bandwidth you’re given is very generous; along with the actual computing ‘budget’ they provide you with being pretty high (with their GPU system). Their website is beautifully designed and works pretty well but is let down by their MySQL system and slightly confusing control panel. You can of course fix the MySQL fault by purchasing a MySQL container at $20/mo, offering excellent response times; but this doubles the monthly cost of the service.

Extra MySQL Packages Are Available

I’d also point out that the Mediatemple terms of use are similar to those found on VPS and dedicated servers, much more relaxed than shared servers. This is still very useful (combined with the high storage space and inclusive bandwidth) for image hosting sites etc that you can’t put elsewhere.

Hopefully this has given you a fairly round view of my time with mediatemple, everybody’s views differ and you’ll have a different experience depending on what cluster you’re on; but I’d suggest a VPS is a better way to go until Mediatemple sort out the annoying MySQL lag.

Posted in Hardware, Software | Tagged , , | Leave a comment

Simple PHP Login Systems and PHP Header – Break them with cURL

Most of the simple, free PHP scripts out there for user login systems have several large flaws in them, and I’ll admit that my earliest sites weren’t safe from what I’m going through today.

cURL is a valuable tool for any PHP developer and has extremely useful applications, one of which is logging into remote sites to post forms. This illustrates a flaw with many sites in that they user header redirects (as shown below) in their login systems to keep people away from pages they shouldn’t see, and log them in and out.

if ($_SESSION['logged'] != 1) {
header("Location: login.php");
}

That very simple bit of code checks to see whether a session has been found where logged = 1. If it doesn’t find one then it will redirect the user to login.php without showing them the page.

The problem here is that header location ONLY works when it’s the first thing on a page, otherwise you’ll see an error and then the rest of the page we shouldn’t be seeing – which is what happens with a cURL request. This means the header location redirect doesn’t work and anyone can grab your “protected” page easily and quickly without logging in.

To solve this quickly (without changing your basic login script at all) make sure you have failsafes! The most simple would be to add a die statement as below so that if your redirect fails, they won’t get to see your private page.

if ($_SESSION['logged'] != 1) {
header("Location: login.php") or die("Please <a href='login.php'>login</a> before accessing this page.");
}

Very simple stuff, but there’s lots of sites without it.

Posted in Coding | Tagged , | Leave a comment