Here's a bastard mysql version, destined to be torn apart by the board. Completely untested, and of course, you'll have to fill in the actual field names and so forth.
<?php
# Current URL
$url = empty($_SERVER['QUERY_STRING']) ? $_SERVER['PHP_SELF'] : $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'];
# Sort Field
if(isset($_GET['sort'])) {
$url = str_replace('&sort='.$_GET['sort'], '', $url);
switch($_GET['sort']) {
case 'a': $sort = 'field_1'; break;
case 'b': $sort = 'field_2'; break;
case 'c': $sort = 'blah_field'; break;
default: $sort = 'field_1'; break;
}
}
else {
$sort = 'field_1';
}
#ASC or DESC
if(isset($_GET['dir'])) {
$dir = 'DESC';
$url = str_replace('&dir='.$_GET['dir'], '', $url);
}
else {
$dir = 'ASC';
$url .= '&amp;dir=d';
}
# Make URL XHTML compatible
$url = str_replace('&', '&amp;', $url);
# Connect, Perform Query
$conn = mysql_connect('server', 'user', 'pass');
mysql_select_db('db', $conn);
$sql = "SELECT field_1, field_2, blah_field
FROM table
WHERE something = 'something'
ORDER BY ".$sort.' '.$dir;
$res = mysql_query($sql) or die(mysql_error());
if(mysql_num_rows($res) > 0) {
# We have rows, make the table
?>
<div class="container">
<table cellspacing="0">
<tr>
<th><a href="<?php echo $url; ?>&amp;sort=a" title="Sort By Field 1">Field 1</a></th>
<th><a href="<?php echo $url; ?>&amp;sort=a" title="Sort By Field 2">Field 2</a></th>
<th><a href="<?php echo $url; ?>&amp;sort=a" title="Sort By Blah Field">Blah Field</a></th>
</tr>
<?php
# Display Results
while($row = mysql_fetch_array($res)) {
?>
<tr>
<td><?php echo empty($row['field_1']) ? '&nbsp;' : $row['field_1']?></td>
<td><?php echo empty($row['field_2']) ? '&nbsp;' : $row['field_2']?></td>
<td><?php echo empty($row['blah_field']) ? '&nbsp;' : $row['blah_field']?></td>
</tr>
<?php
}
?>
</table>
</div>
<?php
}
else {
# Default - No rows returned
echo '<p>No rows found</p>';
}
mysql_close($conn);
?>