Forum Moderators: coopster

Message Too Old, No Replies

Simple Mysql Pagination.

         

dkin

1:22 am on Apr 5, 2005 (gmt 0)

10+ Year Member



I am just trying to have simple pages laid out from my mysql db.

I would like 50 rows per page ordered by rank, I would not like the rank to go below 0 and if you are on the last page I do not want a next link visible.

So I ask you how I do this, this is my script so far but I do not know what I am doing.

Now I am not looking for a rewrite, although it would be nice, simply helping me tune small pieces will help.

function index()
{
global $username, $srow, $link;
##Connect to User Database
$uresult = mysql_query("SELECT * FROM user_char where rank >= '$srow[rank]' order by rank asc limit 50", $link) or die ("query 1: " . mysql_error());

echo '<center><table border="1" cellpadding="5" cellspacing="0" width="100%">'
. '<tr><th colspan="3" align="center">Targets</th></tr>'
. '<tr align="center"><td width="50%"><b>Character</b></td><td width="25%"><b>Gold</b></td><td width="25%"><b>Rank</b></td></tr>';

while ($urow = mysql_fetch_array($uresult))
{

if ($urow['username'] == $username)
{
echo '<tr><td>'.$urow['name'].'</td><td align="right">'.$urow['gold'].' Gold</td><td align="center">'.$urow['rank'].'</td>';

}
else
{
echo '<tr><td><a href="attack.php?target='.$urow['name'].'">'.$urow['name'].'</a></td><td align="right">'.$urow['gold'].' Gold</td><td align="center">'.$urow['rank'].'</td>';
}

}

echo '</table></center>';

$prev = $srow[rank] - '50';

if ($prev <= $rrow['rank'])
{
echo '';
}
else{
echo '<a href="?action=previous_page&start='.$prev.'">PREVIOUS</a>';
}

$next = $srow[rank] + '50';

if ($next >= $rrow['rank'])
{
echo '<a href="?action=next_page&start='.$next.'">NEXT</a>';
}
else{
echo '';
}

echo '</td></tr></table>';
}

}
else{
print 'You Must Login to View this Page';
}

function next_page()
{
global $start, $link;

echo $rows.''.$end_row;

##Connect to User Database
$nresult = mysql_query("SELECT * FROM user_char WHERE rank >= '$start' ORDER BY rank asc limit 50", $link) or die ("query 1: " . mysql_error());
echo '<center><table border="1" cellpadding="5" cellspacing="0" width="100%">'
. '<tr><th colspan="3" align="center">Targets</th></tr>'
. '<tr align="center"><td width="50%"><b>Character</b></td><td width="25%"><b>Gold</b></td><td width="25%"><b>Rank</b></td></tr>';

while ($nrow = mysql_fetch_array($nresult))
{

if ($nrow['username'] == $username)
{
echo '<tr><td>'.$nrow['name'].'</td><td align="right">'.$nrow['gold'].' Gold</td><td align="center">'.$nrow['rank'].'</td>';

}
else
{
echo '<tr><td><a href="attack.php?target='.$nrow['name'].'">'.$nrow['name'].'</a></td><td align="right">'.$nrow['gold'].' Gold</td><td align="center">'.$nrow['rank'].'</td>';
}

}

echo '</table></center>';
$prev = $srow[rank] - '50';

if ($prev <= $rrow['rank'])
{
echo '';
}
else{
echo '<a href="?action=previous_page&start='.$prev.'">PREVIOUS</a>';
}

$next = $srow[rank] + '50';

if ($next >= $rrow['rank'])
{
echo '<a href="?action=next_page&start='.$next.'">NEXT</a>';
}
else{
echo '';
}
}

function previous_page()
{
global $start, $link;

##Connect to User Database
$nresult = mysql_query("SELECT * FROM user_char WHERE rank >= '$start' ORDER BY rank asc limit 50", $link) or die ("query 1: " . mysql_error());
echo '<center><table border="1" cellpadding="5" cellspacing="0" width="100%">'
. '<tr><th colspan="3" align="center">Targets</th></tr>'
. '<tr align="center"><td width="50%"><b>Character</b></td><td width="25%"><b>Gold</b></td><td width="25%"><b>Rank</b></td></tr>';

while ($nrow = mysql_fetch_array($nresult))
{

if ($nrow['username'] == $username)
{
echo '<tr><td>'.$nrow['name'].'</td><td align="right">'.$nrow['gold'].' Gold</td><td align="center">'.$nrow['rank'].'</td>';

}
else
{
echo '<tr><td><a href="attack.php?target='.$nrow['name'].'">'.$nrow['name'].'</a></td><td align="right">'.$nrow['gold'].' Gold</td><td align="center">'.$nrow['rank'].'</td>';
}

}

echo '</table></center>';
$prev = $srow[rank] - '50';

if ($prev <= $rrow['rank'])
{
echo '';
}
else{
echo '<a href="?action=previous_page&start='.$prev.'">PREVIOUS</a>';
}

$next = $srow[rank] + '50';

if ($next >= $rrow['rank'])
{
echo '<a href="?action=next_page&start='.$next.'">NEXT</a>';
}
else{
echo '';
}
}

## $finish Variable found in layout.php
echo $finish;

switch ("$action")
{

case "next_page":
next_page();
break;

case "previous_page":
previous_page();
break;

default:
index();
break;

}

ironik

1:30 am on Apr 5, 2005 (gmt 0)

10+ Year Member



MySQL has tbe ability to accept an offset with results returned, you just need to change your SQL query and add some code to handle the current page. Here's a very simple example:


$resultsPerPage = 10;
$currentPage = is_numeric($_GET['page'])? $_GET['page'] : 1;
$limit = $currentPage * $resultsPerPage;
mysql_query("SELECT * FROM user_char WHERE rank >= '$start' ORDER BY rank asc limit " . $limit . ", " . $resultsPerPage, $connection);

That is a very simplified example, but it should get you on the right track.

dkin

1:57 am on Apr 5, 2005 (gmt 0)

10+ Year Member



ok so how would I display the results?

ironik

3:40 am on Apr 5, 2005 (gmt 0)

10+ Year Member



Exactly how you are now (with a while statement iterating a mysql query resource).

You'll need to impliment some sort of pagination for the site so you can navigate properly, another simple example you could just find the number of pages and output a link for each page:


$totalQuery = mysql_query("SELECT * FROM user_char");
$totalResults = mysql_num_rows($totalQuery);
$totalPages = ceil($totalResults/$resultsPerPage);

$resultsPerPage = 10;
$currentPage = is_numeric($_GET['page'])? $_GET['page'] : 1;
$limit = ($currentPage * $resultsPerPage) - $resultsPerPage;
$limitQuery = mysql_query("SELECT * FROM user_char WHERE rank >= '$start' ORDER BY rank asc limit " . $limit . ", " . $resultsPerPage, $connection);

for ($i = 1; $i <= $totalPages; $i ++)
{
echo 'somepage.php?page=' . $i;
}

Again, this is just a really simple example, you'll need to modify it. I changed the example to store the limit query in a variable $limitQuery and also to calculate the $limit variable properly (sorry, my example before would have given you the wrong results for each page).

jatar_k

4:33 am on Apr 5, 2005 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



so many snippets, you almost feel overwhelmed

I made this very simple one the other day

$paging = ""; 
$paging .= "<td colspan='4' valign='top' align='right'>\n";
$sql1 = "select count(comm_id) as totcomm from stcomment";
$query1 = mysql_query($sql1) or die("<p>oops, couldn't get the commcount: " . mysql_error());
$tcr = mysql_fetch_array($query1);
$totcomm = $tcr['totcomm'];
$numpages = ceil($totcomm/20);
$counter = 0;
while ($counter < $numpages) {
$start = $counter * $perpage;
$pg = $counter + 1;
if ($counter == $offset/$perpage) $paging .= " <b>$pg</b> ";
else $paging .= " <a href='comments.php?s=$start'>$pg</a> ";
//echo "¦ <a href='comments1.php?s=$start'>$pg</a>";
$counter++;
}
$paging .= " </td>\n";

it was the quick work of half an hour so no magic here, I still have to add the next and previous and keep it from just having an endless number of pages

dkin

3:09 am on Apr 6, 2005 (gmt 0)

10+ Year Member



I have no idea what to do with that.

jatar_k

4:14 am on Apr 6, 2005 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



hehe, sry dkin

well, you need to put a query in there of your own so it actually counts the rows in your table

this part
<a href='comments.php?s=$start'>

is the link to the next page which passes a new start which I use in an offset for the limit in my next query

dmmh

6:53 am on Apr 6, 2005 (gmt 0)

10+ Year Member




//global page numbering stuff
if(!isset($_GET['page'])){
$page = 1;
} else {
$page = mysql_real_escape_string($_GET['page']);
}
//end of global page numbering stuff

$max_results = 50; //50 results per page
$from = (($page * $max_results) - $max_results);

$query= 'SELECT * FROM table'. " WHERE id IS NOT NULL LIMIT $from, $max_results";
$result = mysql_query($query) or die ("Error in query: $query " . mysql_error());

killroy

9:40 am on Apr 6, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



To avoid havign to use two queries, I'd recommend to get 1 line more, so for page 2 for example do
LIMIT 50,51

Only display 50 rows, but if there is a 51st row you know you need the next link. Prev links are trivial of course.

SN

dkin

5:56 pm on Apr 6, 2005 (gmt 0)

10+ Year Member



This is the error I get when using your code Jatar. Please Help

Warning: Division by zero in /home/lordsoft/public_html/pt.php on line 47

jatar_k

8:12 pm on Apr 6, 2005 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



I seem to have forgotten one bit

$perpage = 20;
if (!isset($_GET['s']) ¦¦ empty($_GET['s']) ¦¦!is_numeric($_GET['s'])) $offset = 0;
else $offset = $_GET['s'];

is at the top of the page, this could also be changed

$numpages = ceil($totcomm/20);
to
$numpages = ceil($totcomm/$perpage);

$offset is used later in the actual query like so
$sql = "select * from stcomment order by whensub desc limit " . $offset . "," . $perpage;

dkin

12:47 am on Apr 7, 2005 (gmt 0)

10+ Year Member



lol :S <----- Me confused :)

this is what I have, mind pointing me in the right direction?

$perpage = 20;
if (!isset($_GET['s']) ¦¦ empty($_GET['s']) ¦¦!is_numeric($_GET['s']))
{
$offset = 0;
}
else {
$offset = $_GET['s'];
}
$paging = "";
$paging .= "<td colspan='4' valign='top' align='right'>\n";
$sql1 = "select count(username) as user from user_char";
$query1 = mysql_query($sql1) or die("<p>oops, couldn't get the commcount: " . mysql_error());
$tcr = mysql_fetch_array($query1);
$totcomm = $tcr['user'];
$numpages = ceil($totcomm/$perpage);
$counter = 0;
while ($counter < $numpages) {
$start = $counter * $perpage;
$pg = $counter + 1;
if ($counter == $offset/$perpage) $paging .= " <b>$pg</b> ";
else $paging .= " <a href='comments.php?s=$start'>$pg</a> ";
//echo "¦ <a href='comments1.php?s=$start'>$pg</a>";
$counter++;
}
$paging .= " </td>\n";

dkin

5:52 pm on Apr 7, 2005 (gmt 0)

10+ Year Member



can anyone point me in the right direction?

jatar_k

6:29 pm on Apr 7, 2005 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



what is it doing wrong dkin?

dkin

7:28 am on Apr 8, 2005 (gmt 0)

10+ Year Member



I am getting this error

Parse error: parse error, unexpected T_STRING in /home/lordsoft/public_html/pt.php on line 36

Which is this line

if (!isset($_GET['s']) ¦¦ empty($_GET['s']) ¦¦!is_numeric($_GET['s']))

coopster

10:35 am on Apr 8, 2005 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



If you cut and pasted that line into your editor, don't forget that this forum breaks the pipe symbol (¦), so you have to rekey them. Also, make sure there is a space between that last OR clause and your exclamation point character.
if (!isset($_GET['s']) ¦¦ empty($_GET['s']) ¦¦ !is_numeric($_GET['s']))

dkin

6:59 pm on Apr 9, 2005 (gmt 0)

10+ Year Member



Very sorry for dragging this out so long but I have about 1400 people waiting for me to finish this lol.

I am having a heck of a time displaying any of my db info in that loop.I fixed the code from before thanks to coop.

So this is my code


$perpage = '20';
if (!isset($_GET['s']) ¦¦ empty($_GET['s']) ¦¦!is_numeric($_GET['s']))
{
$offset = 0;
}
else {
$offset = $_GET['s'];
}
$paging = "";
$paging .= "<td colspan='4' valign='top' align='right'>\n";
$sql1 = "select count(username) as user from user_char";
$query1 = mysql_query($sql1) or die("<p>oops, couldn't get the commcount: " . mysql_error());
$tcr = mysql_fetch_array($query1);
$totcomm = $tcr['user'];
$numpages = ceil($totcomm/$perpage);
$counter = 0;
while ($counter < $numpages) {
$start = $counter * $perpage;
$pg = $counter + 1;
if ($counter == $offset/$perpage) $paging .= " <b>$pg</b> ";
else $paging .= " <a href='comments.php?s=$start'>$pg</a> ";
//echo "¦ <a href='comments1.php?s=$start'>$pg</a>";
$counter++;
}
$paging .= " </td>\n";

?>

But I dont know where to put the db connection or how to make it loop through the 50 rows I want displayed on each page.

Please Help.

jatar_k

5:28 pm on Apr 10, 2005 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



well, that is just paging

the connection would be before that and you would have to select your rows and display them after wards.

dkin

3:44 pm on Apr 12, 2005 (gmt 0)

10+ Year Member



I am still trying to use this code but would like a hint on how to have the results start on a certain page.

IE my user is rank 132 I would like that page to be displayed first.

Also I am having dificulty with the linking, it looks like I need to use a switch but I am not sure.

please help.

cheers
Dylan

dkin

2:55 am on Apr 13, 2005 (gmt 0)

10+ Year Member



someone please help me, Im doing the best I can :)

ironik

4:15 am on Apr 13, 2005 (gmt 0)

10+ Year Member



if you know the order that you will return data, and you know what number in that order a result will appear (your ranking example) the finding what page that item will appear on is easy:

$perPage = 20;
$positionInResult = 132;
$pagePositionAppears = floor($positionInResult/$perPage); // This returns page number 6 for this example

jd01

11:57 am on Apr 13, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Not very good at deciphering other people's code, so I thought I would give you another example. (I recommend changing the variables to shorter names, they are exploded to full names for comprehension.)

This is how I do it:
$db_host = "www.yourwebhosting.com";
$db_username = "your_user_name";
$db_password = "uh_I_think_you_get_it"
$db_table = "and_so_on";
$db_sort = "what col you want your results ordered by"; // this is the same on every page, so your results on the page will be determined by the starting number. (you can also add ",ASC" or ",DSC" for ascending or descending.)
$db_results_per_page = how many results you want; // no quotes for the number or it won't work.

if(!isset($page)) $page = 1; // If page is not set it is 1
$start = (($page - 1) * $db_results_per_page); // mysql starts at 0, so take one away from the page to make sure you get result 0

$db = mysql_connect($db_host, $db_username, $db_password);
mysql_select_db($db_database, $db) or die ( mysql_error() . "\n" );

$query = "SELECT * FROM ".$db_table." ORDER BY ".$db_sort." LIMIT ".$start.",".$db_results_per_page."; // selects x number of results starting at $start's current value
$result = mysql_query($query);
$head = mysql_fetch_array($result);
$query2 = "SELECT count(*) AS count FROM ".$db_table.";
$result2 = mysql_query($query2);
$row = mysql_fetch_array($result2);

// You could use the WHERE clause you are using or something similar, but I believe php is faster than sql, so you might do it like this make these changes:
(There are a multitude of ways to arrive at your solution, pick the one best for you.)
// $total_pages = 0;
// $rank_counter = 0;
// $result_pages = mysql_query($query);
// while(mysql_fetch_array($result_pages))
// {
// if $rank > 0
// $rank_counter++;
// }
// $total_pages = ($rank_counter/$results_per_page)

// then remove the following line and base you second while loop on a similar counter that breaks when $your_counter = $results_per_page EG while($your_counter <= $results_per_page) and only display results that are greater than 0 with $your_counter++ when a result is displayed

$total_pages = ($row['count']/$db_results_per_page); // sets $total_pages to check and see if you need a next link

while($your_variable = mysql_fetch_array($result))
{
Blah, blah your stuff here for tables, etc.
}

if($total_pages > ($page + 1))
echo "<a href=\"/your/path/here/".($page + 1).".html \">Your next page link text here"</a>\n"; // adds a next link if you have another page.
echo "<br />";
echo "<br />";
if($page > 1)
echo "<a href=\"/your/path/here/".($page - 1).".html \">Your previous page link text here".($page - 1)."</a><br /><br />\n"; // adds a link if you have a previous page

You might need to tweek it some, I use an externally hosted $'s page, so I can easily change anything and not have to scroll the page to find the line, etc. I also mod_rewrite the .html back to php and pass the $page.

(If you are using just php you would change the links to <a href=\"".$PHP_SELF."?page=" .($page + 1). "\">, and ($page - 1) respectively.)

Hope this helps, if you still get stuck, keep posting.

RE your current parse error, they usually happen on or before the line they are recorded on - php looks, expects to find, doesn't find, then breaks... normally within a line or two, but sometimes more.