In previous posts, I wrote a good bit about working with the Google Maps API. Truthfully, I haven’t worked with it since that post.
However, I have had to work with latitude and longitude in PHP, and there are some practices that I’ve begun to use that I think can serve us well when working with coordinates or floating point values, in general.
In the following bit of code, I’ll break down the approach I’ve used and why I’ve done so. But I do want to be clear that if you’re reading this in relationship to the Google Maps API, there’s not much I can offer in the way of how this works and the current version of their API.
Latitude and Longitude in PHP
Whenever you’re working with latitude and longitude in PHP, you’re working with floating point values, right? So you never want to parse them into anything less than that; otherwise, you’re losing data, and you’re not going to be able to locate whatever it is you’re trying to locate.
So for all intents and purposes, let’s assume that you have information coming into the server and you need to work with it using PHP.
The two things you want to remember are:
- sanitize the incoming data,
- make sure it’s converted to a floating point value.
This can be done through the use of PHP’s filter_var and floatval function’s which I’ll talk about momentarily. Note, however, that if the result of floatval does not return a floating point, you need to have a graceful way to handle that.
According to the manual, floatval can return the following:
The float value of the given variable. Empty arrays return 0, non-empty arrays return 1.Strings will most likely return 0 although this depends on the leftmost characters of the string. The common rules of float casting apply.
We’ll look how to handle this more gracefully later in the post.
Parsing Incoming Latitude and Longitude
Let’s assume that the incoming values are in PHP’s $_REQUEST collection (which refer to the HTTP requests coming into the server) keyed as acme-demo-latitude and acme-demo-longitude.
We can retrieve them like this:
But this isn’t enough. First, we need to use filter_var to make sure the data is sanitized and follows the floating point schema:
Next, I find it helpful to use floatval to parse the result as a floating point value. This leaves te following block of code looking like this:
After which you’re free to use it. But remember, we still need to make sure that the values returned are floating point values.
Validating The Data
Now that we have the information, we need to make sure that it looks good. And if it doesn’t we need to handle it appropriately. If it’s not, then we can simply:
- return false from the function from which it’s contained,
- throw an exception and allow the caller to handle it however it sees fit.
Each of these examples may look like this:
Ultimately, though, the decision is yours on how to handle the values when they are not in the proper format once parsing them.
Are These Best Practices?
To be honest, I doubt it. I know that these are the things that I’ve been using and that I’ve found useful. It also provides a defensive, resilient way to make sure your values are correct.
But if there are better ways to do this, then I’m open to hearing them in the comments.
Hey Tom,
You’re sure keeping the subjects on your blog very varied! :)
A couple of notes regarding your code examples:
floatval()
(just likeintval()
and their cousins that are so often used in WP code) is a PHP 4 function. You should prefer a real cast ($float = (float) $value
) instead, as it doesn’t come with the overhead of a function call.The latitude and longitude values also have upper and lower bounds that you should try to enforce.
Finally, you might want to consider using value objects, to abstract all this stuff away and enforce it in a transparent way. This would then make your code look like this:
$latitude = new Latitude( $_REQUEST['acme-demo-latitude'] );
$longitude = new Longitude( $_REQUEST['acme-demo-longitude'] );
These are reusable as well, so you can just drop them into a project where you need them.
Cheers,
Alain
I do what I can :)
Function calls don’t bother me too much depending on the context. There’s overhead, sure, but I’d be interested in benchmarking them in certain conditions.
Then again, clearly casting values when you know their type are really the better practice.
A good point and one I didn’t consider.
Indeed. And using initial posts like this help to start discussions on abstractions exactly like you’ve shown above. I mean even grabbing values from the
$_REQUEST
has a level of validation that needed prior to (or maybe just after) passing it into those objects.Regardless, the reusability is certainly better.