We've seen loads of bad date handling, but as always, there's new ways to be surprised by the bizarre inventions people come up with. Today, Tim sends us some bad date sorting, in PHP.
// Function to sort follow-ups by Date
function cmp($a, $b) {
return strcmp(strtotime($a["date"]), strtotime($b["date"]));
}
// Sort the follow-ups by Date
usort($data, "cmp");
The cmp
function rests in the global namespace, which is a nice way to ensure future confusion- it's got a very specific job, but has a very generic name. And the job it does is… an interesting approach.
The "date" field in our records is a string. It's a string formatted in YYYY-MM-DD HH:MM:SS
, and this is a guarantee of the inputs- which we'll get to in a moment. So the first thing that's worth noting is that the strings are already sortable, and nothing about this function needs to exist.
But being useless isn't the end of it. We convert the string time into a Unix timestamp with strtotime
, which gives us an integer- also trivially sortable. But then we run that through strcmp
, which converts the integer back into a string, so we can do a string comparison on it.
Elsewhere in the code, we use usort
, passing it the wonderfully named $data
variable, and then applying cmp
to sort it.
Unrelated to this code, but a PHP weirdness, we pass the callable cmp
as a string to the usort
function to apply a sort. Every time I write a PHP article, I learn a new horror of the language, and "strings as callable objects" is definitely horrifying.
Now, a moment ago, I said that we knew the format of the inputs. That's a bold claim, especially for such a generically named function, but it's important: this function is used to sort the results of a database query. That's how we know the format of the dates- the input comes directly from a query.
A query that could easily be modified to include an ORDER BY
clause, making this whole thing useless.
And in fact, someone had made that modification to the query, meaning that the data was already sorted before being passed to the usort
function, which did its piles of conversions to sort it back into the same order all over again.