picture of Rod
When I wrote my first article on this subject, my intention was NOT to provide working code but rather to provide a thought process that individuals could use to solve their own unique problems. Judging by some of the comments and questions posted here, that was not what most people wanted.
Unfortunately, I have not the time or desire to write code that will work for all individuals in all cases. The following code will work fine (with, possibly, some light changes to the HTML to suit your needs/tastes) in most instances. Since this code ONLY provides incremental page links, it is not suited to instances where there will be many resulting pages, but should be OK for instances with between 0 to approximately 30 pages depending on the width of the area in which you place the code.
That said, let's move on to the code itself:

<?php

function pagenav() {
    global 
$limit,$offset,$numpage,$where;
    if (
$where) {
        
$safewhere=urlencode($where);
    }
    echo 
"
    <TABLE CELLPADDING=0 BORDER=0 CELLSPACING=5 WIDTH=100>
    <TR>
        <TD ALIGN=RIGHT>"
;

        if (
$offset>=$limit) {
            
$newoff=$offset-$limit;
            
            echo 
"<A HREF=\"$PHP_SELF?offset=$newoff&where=$safewhere\">
                &lt;-- PREV</A>
                </TD>"
;
        } else {
            echo 
"&lt;-- PREV";
        }

        echo 
"<TD ALIGN=CENTER> &nbsp; ";

        for (
$i=1;$i<=$numpage;$i++) {
            if (((
$i-1)*$limit)==$offset) {
                print 
"$i ";
            } else {
                
$newoff=($i-1)*$limit;

                echo 
"<A HREF=\"$PHP_SELF?offset=$newoff&where=$safewhere\">
                    $i</A> "
;
            }
        }
        echo 
"&nbsp; </TD>
        <TD ALIGN=LEFT>"
;
        if (
$offset!=$limit*($numpage-1)) {
            
$newoff=$offset+$limit;
            echo 
"<A HREF=\"$PHP_SELF?offset=$newoff&where=$safewhere\">
                NEXT--&gt;</A>
                </TD>"
;
        }else{
            echo 
"NEXT--&gt;</TD>";
        }
        echo 
"</TR>
    </TABLE>"
;

// END FUNCTION

?>
The script relies upon three to four outside variables. The first two, $limit and $offset can be set by adding the following lines at the beginning of your code:

<?php

// set this to the number of results you wish on each page
$limit=20

// if no offset has been passed, offset should be 0
if (!$offset) {
    
$offset=0
}

?>
The $where variable is a little difficult to explain. If your code generates a dynamic where clause based upon data passed to the script, you will need to construct the $where variable. It is not entirely safe to pass the EXACT where clause in the query string of the URL, so you can "encode" the where clause. NOTE: if your where clause is entirely static (i.e. is always the same for each instance of the script) or your query does not utilize a where clause you need do nothing.
For example, let's say our where clause is based on two variables passed to the script: $one and $two, and would be used in the following manner in the where clause of our query:
where one='$one' and two='$two'
We would want to add this code somewhere at the top of the script:

<?php

if (!$where// where was not passed {
    
if (empty($one) || empty($two)) {
           
// some error handling as $one 
        //and/or $two not passed to initial page
    
}
    
$where="$one|$two";
}
// NOTE: if a pipe (|) may be in the value 
//of $one or $two, use a different delimiter
$data=explode('|',$where); 
$query_where="where one='$data[0]' AND two='$data[1]'";

?>
How this will be used will become clear in a moment. NOTE: if you do not have a where clause, do not use the above code in your script. No modificatins to the function are neccesary however.
The last variable we need is $numpage, which is the number of pages that will display. In short, it is the number of records divided by $limit, rounded up. We need to preform two queries for this operation to work successfully. The first query returns the number of rows that would be returned without a limit:

<?php

$result
=mysql_query("select count(*) from tablename $query_where");
list(
$numrec)=mysql_fetch_row($result);
#calc num pages
$numpage=intval($numrec/$limit);
if (
$numrec%$limit$numpage++; // add one page if remainder

?>
Now, we can do our query that returns the actual records we will display:

<?php

$result
=mysql_query("select * from tablename $query_where limit $offset,$limit");

?>
The only thing remaining is to call the function. But what if our query is limited in such a way as there will only be one set of results? We certainly don't want to display page links if there are no other pages!

<?php

if ($numpage>1) {
    
pagenav();
    print 
"<P>";
}

?>
will solve this problem.
In conclusion our page would look something like this:

<?php

function pagenav() {
    global 
$limit,$offset,$numpage,$where;
    if (
$where) {
        
$safewhere=urlencode($where);
    }
    echo 
"
    <TABLE CELLPADDING=0 BORDER=0 CELLSPACING=5 WIDTH=100>
    <TR>
        <TD ALIGN=RIGHT>"
;

        if (
$offset>=$limit) {
            
$newoff=$offset-$limit;
            
            echo 
"<A HREF=\"$PHP_SELF?offset=$newoff&where=$safewhere\">
                &lt;-- PREV</A>
                </TD>"
;
        } else {
            echo 
"&lt;-- PREV";
        }

        echo 
"<TD ALIGN=CENTER> &nbsp; ";

        for (
$i=1;$i<=$numpage;$i++) {
            if (((
$i-1)*$limit)==$offset) {
                print 
"$i ";
            } else {
                
$newoff=($i-1)*$limit;

                echo 
"<A HREF=\"$PHP_SELF?offset=$newoff&where=$safewhere\">
                    $i</A> "
;
            }
        }
        echo 
"&nbsp; </TD>
        <TD ALIGN=LEFT>"
;
        if (
$offset!=$limit*($numpage-1)) {
            
$newoff=$offset+$limit;
            echo 
"<A HREF=\"$PHP_SELF?offset=$newoff&where=$safewhere\">
                NEXT--&gt;</A>
                </TD>"
;
        }else{
            echo 
"NEXT--&gt;</TD>";
        }
        echo 
"</TR>
    </TABLE>"
;

// END FUNCTION

// set this to the number of results you wish on each page
$limit=20

// if no offset has been passed, offset should be 0
if (!$offset$offset=0

if (!
$where) {
    if (empty(
$one) || empty($two)) {
        
// some error handling as $one and/or 
        //$two not passed to initial page
    
}
    
$where="$one|$two";
}

// NOTE: if a pipe (|) may be in the value 
// of $one or $two, use a different delimiter
$data=explode('|',$where);
$query_where="where one='$data[0]' AND two='$data[1]'";

$result=mysql_query("select count(*) from tablename $query_where");

list(
$numrec)=mysql_fetch_row($result);

#calc num pages
$numpage=intval($numrec/$limit);

if (
$numrec%$limit) {
    
$numpage++; // add one page if remainder
}

$result=mysql_query ("select * from tablename $query_where limit $offset,$limit");

//<!-- HTML headers and other non-relevent stuff -->

if ($numpage>1) {
    
pagenav();
    print 
"<P>";
}
//<!-- result display loop -->
if ($numpage>1) {
    
pagenav();
    print 
"<P>";
}

?>
Happy coding.
Rod K