SiteCrafting Blah Blah Blog
Dec. 1, 2006 at 8:41am
Use Functions for Readable Code
Code Soup versus Short Stories
On my way to meeting with a client, I got into a conversation about using functions in your code. One of the guys learned to write assembly first, and so his stance was that creating functions was only feasible when you used the same code more than (about) three times. That view makes a certain sense - don't deal with the overhead of creating tons of functions for stuff you'll seldom use.
I argue that you should use functions where ever possible, first because it makes code easier to generalize (and thus re-use), but also because it makes code much more readable.
To illustrate my point, here are two fictional but entirely probable examples. And here's some guidelines:
- Whitespace does not count as a line, but { and } do.
- Only lines of code that are unique to the specific example will be counted, because if you can use 8 lines of code by writing one, it's really only one new line of code.
- Statement format is consistent throughout - that means that if I condense 3 statements into a single line of code, condensation is done universally
Example 1: Get All Rows From a Table
The Assembly (aka Code Soup) Way:
$sql = "SELECT * FROM table";
$result = mysql_query($sql);
if($result) {
$rows = array();
while($row = mysql_fetch_array($result)) {
$rows[] = $row;
}
}
That's pretty straight forward, and takes 8 lines of code. Pretty simple, and easy to understand for most programmers with experience. The main drawback is that code is only useful in that one situation.
Now my way:
$rows = getRows('table');
function getRows($table) {
$sql = "SELECT * FROM $table";
$result = query($sql);
return fetchAll($result);
}
function query($sql) {
return mysql_query($sql);
}
function fetchAll($result) {
$rows = array();
while($row = fetch($result)) {
$rows[] = $row;
}
return $rows;
}
function fetch($result) {
return mysql_fetch_array($result);
}
There's 19 lines of code in this method, however only one is unique to this situation (the first one - all the functions can be reused). This method is also readable by just about anyone including your boss (ok, so maybe that's not really a good thing). It's also terrifically easy to maintain and extend this code. True, in two cases (query and fetch), I'm just renaming PHP functions, but that makes them so much easier to type, it's worth doing to save time.
Example 2: Displaying input fields for a form in a table
This is a pretty common occurrence in web development. Let's say you want to create a form, and use a table to format it on the page nicely. We know that designing with tables is bad, but sometimes it happens. We'll have four fields in our table: a text field, a textarea, a file input, and a textarea following that. Think of this as a heading, some text, an image, and a caption for that image. Here's how the Code Soup version might look: (I've left off tag attributes except input types for brevity's sake)
echo '<form>';
echo '<table>';
echo '<tr><td>Heading</td><td><input type="text" name="heading" /></td></tr>';
echo '<tr><td>Content</td><td><textarea name="content"></textarea></td></tr>';
echo '<tr><td>Image</td><td><input type="file" name="image" /></td></tr>';
echo '<tr><td>Caption</td><td><textarea name="caption"></textarea></td></tr>';
echo '</table>';
echo '</form>';That's 8 lines of code, all legible and usable. But we can do better. Notice that we have two textareas, and the only thing that changes between them is the name of the field. We can generalize this, and also make that fragment much more readable, like this:
echo '<form>';
echo '<table>';
echo inputRow('Heading', 'heading');
echo textareaRow('Content', 'content');
echo fileRow('Image', 'image');
echo textareaRow('Caption', 'caption');
echo '</table>';
echo '</form>';
function inputRow($label, $name) {
return '<tr><td>'.$label.'</td><td><input type="text" name="'.$name.'" /></td></tr>';
}function fileRow($label, $name) {
return '<tr><td>'.$label.'</td><td><input type="file" name="'.$name.'" /></td></tr>';
}
function textareaRow($label, $name) {
return'<tr><td>'.$label.'</td><td><textarea name="'.$name.'"></textarea></td></tr>';
}
Again, the functions use slightly more lines of code than the Soup version, but there are two huge benefits from using functions. Number one is increased legibility, and number two is reuse. The main code block that uses functions is a whole lot easier to work with than the one that doesn't. Also, you can use those functions anywhere on your site, and get rid of the overhead of writing out '<tr><td>...</td></tr>' every time you just want to add a text input to the form. I used this same method to shrink part of our CMS from ~700 lines of code to less than 100, and it's a lot easier to modify now.
Properly using functions and classes can help your coding a lot. It can speed up development, make maintenance easier, and even help you make better software. So go function crazy. If you create a function that makes your life easier, try to make that function even easier to use. But remember, functions shouldn't do two (or more) different things. If you have a function that updates a database and prints out a page template, split it into two functions. Also, never, never ever declare a function in multiple places in the same project. If you have many instances of a function to update a database, or capture form submissions, it totally defeats the purpose of making functions in the first place.
Posted in Coding Techniques, PHP, Software Engineering by Dave Poole
Comments (1)
hi guy i too use these kind of codings. its my nature to split repeatitive tasks into functions. we are going on the same boat. if you are interested with me contact through email.
good work done by u.
regards
ss_senthil
1 | Left by ss_senthil | May. 19, 2007 at 4:52am