Category: General

Writing Function Code To Be More Readable

1 October, 2008 | General | No comments

Last month I started writing functions in a particular way, which has made my life as a programmer much easier on more than one occasion. No matter how many comments or verbose parameter names you put in you can end up writing code that you will get lost in. The reason is simple. Lets say you had a function that took in a couple of parameters.

function myFunction($intNum1,$intNum2){
 // function does something
}

Normal practice is to check the parameters to make sure that they are what you expected them to be before continuing on with the rest of the function. Lets say that we only want the numbers to be in a range. If they are not in the range the function should return false. Many programmers might start of writing something like this.

function myFunction($intNum1,$intNum2){
 if($intNum1 > 0 && $intNum1 < 1000){
  if($intNum2 > 0 && $intNum2 < 1000){
   // do something with the numbers.
   return $value;
  }else{
   return false;
  }
 }else{
  return false;
 }
}

This code will still produce the desired effect of checking to see that the numbers are within a range, but there is a simpler and more elegant way of doing this. For example, what if you wanted to add a third parameter, or a fourth? Having nested if statements is hard enough, but when you get to four levels things get a bit silly.

Here is the same code, but refactored in a way that allows for better readability and maintenance. Notice that the if statement logic has been reversed.

function myFunction($intNum1,$intNum2){
 // check parameter 1
 if($intNum1 < 0 && $intNum1 > 1000){
  return false;
 }
 // check parameter 2
 if($intNum2 < 0 && $intNum2 > 1000){
  return false;
 }
 // do something with the numbers.
 return $value;
}

This way, we get past all of the logic checking before getting down to what we want the function to do, and it is readable. Also, if you wanted to add another parameter you would just add another if statement to check that parameter. There if no juggling of nested statements or complicated syntax.

The above function also doesn’t take into account the fact that the parameters might not be numbers, additional checking can be added at the top of the function to account for this.

I have posted this in the general category because I have used this technique in at least 3 different languages since I started doing it in PHP. All of the code written here is in generic PHP like syntax, but the idea stands. Hopefully, you should get something out of this as well.

Finding Missing Values In A MySQL Table

19 September, 2008 | General | 2 comments

If you have a table of incremental values it can be hard to find out which ones are missing. The only solution might be to write a script to get all the data from the database and see which ones are missing. However, there is a way of doing this without using a script.

Using a standard select query like this:

SELECT * FROM table;

Gets the following data:

1
3
10
23

We can see that values are missing, but which ones? The following query will show us where the gaps are in the data of the table.

SELECT t1.id+1 as Missing
FROM table as t1
LEFT JOIN table as t2 ON t1.id+1 = t2.id
WHERE t2.id IS NULL
ORDER BY t1.id;

Produces the following result.

2
4
11
24

However, this only tell us where the gaps are, not how long they are. To get the range of where the gaps from and to we need to do something a little more complex.

SELECT
t1.id+1 AS 'Missing From',
MIN(t2.id) - 1 AS 'To'
FROM table AS t1, table AS t2
WHERE t1.id < t2.id
GROUP BY t1.id
HAVING t1.id < MIN(t2.id) - 1;

This query gives the following result.

Missing From To
2 2
4 9
11 22

Using this dataset we can figure out where the gaps in the data are and perhaps do something with them.

Find Longitude And Latitude Of PostCode or ZipCode Using Google Maps And PHP

4 September, 2008 | General | No comments

Converting from PostCode to map reference is far from accurate, but it can be done using the Google Maps API. You can get a Google Maps API key from Google by just asking for it, although you are limited to a certain number of requests each day.

Google Maps usually works through JavaScript, but it is possible to ask Google to return the data in JSON format and then use the PHP function json_decode() to decode the information into a usable array format. To get Google to return the data in JSON you must pass the parameter "output=json" in your query string.

The following function can take a postal code and convert it into longitude and latitude.

function getLatLong($code){
 $mapsApiKey = 'your-google-maps-api-key';
 $query = "http://maps.google.co.uk/maps/geo?q=".urlencode($code)."&output=json&key=".$mapsApiKey;
 $data = file($query);
 // if data returned
 if($data){
  // convert into readable format
  $data = json_decode($data[0]);
  $long = $data->Placemark[0]->Point->coordinates[0];
  $lat = $data->Placemark[0]->Point->coordinates[1];
  return array('Latitude'=>$lat,'Longitude'=>$long);
 }else{
  return false;
 }
}

The function can be used in the following way. To keep with the theme, the following two postal codes are two UK and USA office locations of Google.

print_r(getLatLong('SW1W 9TQ'));
print_r(getLatLong('10011'));

This produces the following output.

Array
(
 [Latitude] => 51.489943
 [Longitude] => -0.154065
)
Array
(
 [Latitude] => 40.746497
 [Longitude] => -74.009447
)

I have tried this with UK and USA postal codes, but it would be interesting to see if it works with any other codes. Also, the query currently looks at google.co.uk, but that is only because I am based in the UK. You should change this to the nearest Google domain, so if you are based in the US then change this to google.com.

Installing XDebug With PHP

21 August, 2008 | General | No comments

XDebug is an excellent debugging solution that will give you a more detailed indication of what is wrong in your code. Here is an example of trying to divide two variables that have a value of 0.

  1. Get XDebug (RC3) to match my php (Windows, 5.1.4) – http://xdebug.org
  2. Put it into a directory that you can remember, for example, I put it into my PHP directory at C:\php5\
  3. Open your php.ini file and enter the following lines. If the zend_extension_ts value has been set elsewhere then comment this out.

[xdebug]
xdebug.remote_enable=1
xdebug.remote_host="localhost"
xdebug.remote_port=9000
xdebug.remote_handler="dbgp"
zend_extension_ts="C:\php5\php_xdebug-2.0.3-5.2.5.dll"

  1. Restart your Apache server and run phpinfo() to see if the instillation has taken.

You will now be able to see detailed output for each of your errors.

Remember that these errors still follow the same rules as normal errors. You must still turn on the display_errors directive and set the appropriate error reporting level to get PHP to display any errors at all.

Calculate Distance Between Two Geographical Points With PHP

16 June, 2008 | General | No comments

Use the following function to work out the distance between two geographical points. Geographical points are usually longitude and latitude, in degrees. The first thing to do is to convert these values into radians (using the deg2rad() PHP function) so that we can work with them. The four basic parameters used are the longitude and latitude values for the two points. The optional fifth value is to have the end value returned in miles, rather than kilometres.

function getDistance($a_lat,$a_lng,$b_lat,$b_lng,$mi=false){
 ($mi ? $radius=6371 : $radius=10253);
 $a_lat = deg2rad($a_lat);
 $a_lng = deg2rad($a_lng);
 $b_lat = deg2rad($b_lat);
 $b_lng = deg2rad($b_lng);
 if($a_lat==$b_lat && $a_lng==$b_lng){
  // two distances are the same
  return 0;
 }
 if((sin($b_lat)*sin($a_lat) + cos($b_lat)*cos($a_lat)*cos($b_lng-$a_lng))>1){
  return $radius * acos(1);
 };
 return $radius * acos(sin($b_lat)*sin($a_lat)+cos($b_lat)*cos($a_lat)*cos($b_lng-$a_lng));
}

Here are some examples of the code in action.

echo getDistance(40.995827,-94.370559,63.439031,84.723732); // 8402.1830291634
echo getDistance(-23.782270,134.078645,-23.782626,134.065365); // 1.3518544215203

To print out these results in miles you can set the fifth parameter to be true.

echo getDistance(40.995827,-94.370559,63.439031,84.723732,true); // 13521.830575736
echo getDistance(-23.782270,134.078645,-23.782626,134.065365,true); // 2.175571085206