SiteCrafting Blah Blah Blog
Jan. 26, 2007 at 4:14pm
Making a PHP Script Timer
I've been ranting about a lot of things lately, but not many of them are related to my job description. I want to take a bit of time, and go back to good old PHP, CSS, and Javascript. Today, I'm going to go over how to create a execution timer that will let you know how much time has passed since it started. There are a number of benefits to using one of these things, for example to track down why a script would take 77 seconds to complete rather than 3 or less. (It was a bloated SQL query)
First off, we need to figure out what kind of information we need. The only data we'll be dealing with is a time stamp, but we'll need a few functions. For example, we'll need a function to start the timer, and minimally one to tell us how much time has passed since it was started.
It would be pretty simple to make this timer with procedural programming, ie functions, but I'm going to use an object simply for the encapsulation issue - I can store all variables and functions inside the object and not worry about scoping and how information gets passed around. The functions aren't such a big deal, but this is really helpful for the time variable.
So, here's Timer, revision 1:
class Timer {
var $time;
function set() {
list($usec, $sec) = explode(" ", microtime());
$this->time = ((float)$usec + (float)$sec);
}
function elapsed() {
list($usec, $sec) = explode(" ", microtime());
$now = ((float)$usec + (float)$sec);
return $now - $this->time;
}
}
Analysis:
First off, it takes two lines of code to initialize, namely $timer = new Timer(); and $timer->set(); It would be better if we could use one line to start it.
Second, the method to get the current time is used twice. Since they are identical, why not make it a function?
Timer, revision 2:
class Timer {
var $time;
function Timer() {
$this->set();
}
function set() {
$this->time = $this->now();
}
function elapsed() {
return $this->now() - $this->time;
}
function now() {
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
}
Analysis:
We took care of both problems from last revision, but it's not done yet. What happens if, after creating the timer, you want to reset it to the current time? Since we're explicitely calling the set() function, this isn't immediately possible. Sure, it could be done by an explicit call to the set() function, but that can get confusing.
Grasshopper: "The timer doesn't need to have the set function called?"
PHP Guru: "No, the object does that automatically."
Grasshopper: "So why do I have to call the set function?"
Guru: "You must call the set function whenever you wish to set the timer time to the current time."
Now that just doesn't make sense. Set is something you do to start a thing, and the functionality that was described there was more like a reset action. So, let's add a reset function. This could be done a couple of ways. Reset could just call $this->set(), but then you end up with two functions with identical functionality. Instead, why not just rename set to reset? The user never sees the initial reset action, so it won't be confusing, and they can use the reset function and know exactly what it does every time.
Final Thoughts:
The now() function is kind of akward. It is possible to use get the time as a float right from that function via a boolean flag, but that wasn't added until PHP 5.1.0, and so it wouldn't work universally.
It would be possbile to make $time an array, and allow labels to be set on start times. It wouldn't be difficult, and the semantic benefits of implementing that would be very big. However, I have other plans in mind that I'll share next time when I create an interface for this to be used on any website.
Posted in PHP, Software Engineering by Dave Poole
Comments (0)
Add your comment below