Computer Problems

March 12th, 2009

At some point in between feeding my Twitter addiction and getting a Poker website ready I decided to reformat my big computer after putting up with a few problems for a long, long time. Silverlight was bombing on me, Google Chrome was locking up (blaming Flash) and nothing really worked as it was meant to.

The initial reformat and reinstall went OK, but during the Windows Update->Reboot cycle I got a Blue Screen of Death and things went downhill from there.

My SATA refused to boot. Thinking this could simple be a corrupt MBR problem I booted from my XP CD into the recovery console, tried FIXMBR and FIXBOOT and restarted. I got the same problem – invalid system disk – an decided to reformat again completely. Two hours town the pan so far, but what the hey.

No deal – I still can’t boot from SATA, so I waded through the BIOS options, resetting to safe defaults and going from there, and still my SATA won’t fire up. I eventually removed the Work drive to a safe place and reformatted my backup drive – a 250GB PATA that’s normally in a removable mobile rack – to boot from. This went OK, and I installed Windows, Office and all the combined updates for both.

What’s annoying is that the SATA drives themselves are absolutely fine, mounting in Windows no problem – I just can’t boot from the damned things. I’ve tried all three that I own, two 120s and a 250GB, and they all respond the same. No booting.

I still needed a backup drive, so I plonked down £9.98 on a SATA mobile rack and reformatted the 250 SATA for use as a backup. The idea is that I copy all the files over from C: and D: (now partitions on the 250 PATA, rather than individual SATAs) using SyncToy 2.0 and yank it to store in a safe place. I originally had both my work drive and backup drive encrypted with TrueCrypt, but I just don’t want to push my luck right now.

So now I he a pair of 120GB SATAs sat doing nothing. I could possibly set them up in a simple striped RAID0 config so store my work on, then reformat the PATA as one big lump, but do I really want to go through all that hassle? It’s not as if I need the space.

Sigh… Bloody computers.

How to divide a list of results into pages in PHP

March 9th, 2009

There comes a time when a list of records output by a MySQL query becomes too long to realistically display on a single page, and the programmer wants to break it up into pages. It might be log activity, forum posts or whatever, but the principle is the same – we only want to view a manageable section of the entire record list.

Let’s assume we’re dealing with a set of forum posts in a thread. Your query would take a unique number for the thread ($threadId) and you would pull out a list of posts like this:

<php
 $postSQL="SELECT * FROM posts WHERE (THREAD=$threadId) ORDER BY ID";
 $posts = mysql_query($postSQL) or die(mysql_error());
 while($post=mysql_fetch_array($posts)) {
  // display posts here
 }
?>

This would return all of the posts for this thread in order of creation – ID being the master key for this table.

To split this into pages, we first need to decide how many posts we want per page. Once we have decided on this, we can see how many lines our mysql_query(), above, returns and calculate the number of pages. After that we can decide which page to show and calculate which posts go on that page.

Here’s the altered code:

<?php
 $postSQL="SELECT * FROM posts WHERE (THREAD=$threadId) ORDER BY ID";
 $posts = mysql_query($postSQL) or die(mysql_error());

 $postCount   =mysql_affected_rows();
 $postsPerPage=25;
 $pageCount   =ceil($postCount/$postsPerPage);
 $pageNum     =min(max(1, (int)$_GET['page']), $pageCount);
 $firstPost   =($pageNum-1)*$postsPerPage;
 $lastPost    =min($firstPost+$postsPerPage, $postCount);

 $posts = mysql_query("$postSQL LIMIT $firstPost, $postsPerPage") 
 or die(mysql_error());
 while($post=mysql_fetch_array($posts)) {
  // display posts here
 }
?>

As you can see, we call mysql_query() twice now – the first time to get the total number of posts and the second time to get the subset of those posts once we have decided which ones we want. The highlighted green section shows what has been added, and I’ll go through them here:

$postCount =mysql_affected_rows();

Records the total number of posts returned. We need this so we can calculate how many pages we have in total using…

$postsPerPage=25;

This is how many posts we want on a single page. You can store this in a table for easy altering, or allow it to be overwritten from the URL so that users can decide on their own page sizes.

$pageCount =ceil($postCount/$postsPerPage);

The number of pages is the number of posts divided by the number of posts per page, and rounded up, so ‘30 posts at 25 posts per page’ would return two pages.

$pageNum =min(max(1, (int)$_GET['page']), $pageCount);

Slightly more tricky to read, this line limits the number of the page to be displayed between 1 and the total number of pages, taking into account any page number specified in the URL with ‘&page=’, even if a value is not given.

$firstPost =($pageNum-1)*$postsPerPage;

We need to know the record position – not the ID – of the first post so that we can tell MySQL where to start counting from. This number starts at zero whereas your ID would start at one.

$lastPost =min($firstPost+$postsPerPage, $postCount);

We don’t actually need $lastPost for anything in this example, but it’s nice if you want to display a message along the lines of “Showing posts 25 to 50 of 376″. This value is the actual ID of the last post on the page, so it starts at one and never goes above $postCount.

$posts = mysql_query(“$postSQL LIMIT $firstPost, $postsPerPage”)
or die(mysql_error());

Finally we run your original SQL statement – here held in $postSQL – a second time but with our calculated limits applied.