 |
Account Login
|
 |
 |
Latest Articles
|
 |
 |
IRC Channel
|
 |
 |
Associates
|
 |
 |
Associates
|
 |
|
 |
|
 |
|
 |
04-16-2009, 02:00 PM
|
#1 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Pagination Function
Hey guys, here's the pagination function that I've been working on. It is based off of Websavvy's pagination program so I don't want to take full credit for it. Everything works as I want to except one feature and I will explain that later. But here's the code.
Code:
/* GET CURRENT PAGE */
$get_page = $_GET['p'];
/* SET PAGE LIMIT TO 25 FOR CURRENT TESTING */
$page_limit = "25";
/* QUERY TO GET TOTAL NUMBER OF ENTRIES FOR PAGINATE FUNCTION */
$query_total = "SELECT * FROM schedules";
function pagination($get_page,$display,$query_total,$page_limit) {
/* SET SOME VARIABLES */
if(!$get_page) $p = 1;
if(!$display) $display = 5;
$page_next = ($get_page + 1);
$page_prev = ($get_page - 1);
/* GET TOTAL NUMBER OF ENTRIES FIRST */
$results = mysql_query($query_total);
$totalrows = mysql_num_rows($results);
/* CALCULATE LAST PAGE LINK */
$page_last = ceil($totalrows/$page_limit);
/* USE $start VAR FOR DATABASE QUERY ex: LIMIT $start,$page_limit */
$start = ($get_page - 1) * $page_limit;
$starting_no = $start + 1;
if (($totalrows - $start) < $page_limit) {
$end_count = $totalrows;
} elseif ($totalrows - $start >= $page_limit) {
$end_count = $start + $page_limit;
}
/* CREATE PAGES TO DISPLAY */
for ($i=1; $i<=$page_last; $i++) {
if ($i != $get_page) $display_pages[] = " <a href=\"$_SERVER[PHP_SELF]?p=$i\">$i</a>";
else $display_pages[] = " $i";
}
/* IF ON PAGE 1, UNLINK FIRST AND PREV LINKS */
if($get_page == 1) {
$first = "First";
$prev = "Prev";
}else{
$first = "<a href=\"$_SERVER[PHP_SELF]?p=1\">First</a>";
$prev = "<a href=\"$_SERVER[PHP_SELF]?p=$page_prev\">Prev</a>";
}
/* IF ON LAST PAGE, UNLINK LAST AND NEXT LINKS */
if($get_page == $page_last) {
$last = "Last";
$next = "Next";
}else{
$last = "<a href=\"$_SERVER[PHP_SELF]?p=$page_last\">Last</a>";
$next = "<a href=\"$_SERVER[PHP_SELF]?p=$page_next\">Next</a>";
}
return (array($first,$prev,$display_pages,$next,$last,$totalrows,$starting_no,$start,$page_limit,$end_count));
}###END FUNCTION
list($first,$prev,$display_pages,$next,$last,$totalrows,$starting_no,$start,$page_limit,$end_count) = pagination($_GET[p],5,$query_total,$page_limit);
echo "<span class=\"style13\">" . "$first | $prev" . implode(' ',$display_pages) . " $next | $last" . "</span>";
Code:
OUTPUT YOUR RECORDS: SECOND QUERY USING LIMIT
$query2 = "SELECT * FROM schedules LIMIT $start,$page_limit";
$result2 = mysql_query($query2);
etc etc etc......
Ok, so here is what the output is:
First | Prev 1 2 3 4 Next | Last
and
Viewing Items (1 - 25 of 76 Entries)
Everything works pretty well. When you are on the first page,
the "First" and "Prev" gets unlinked since there's no need to click on them. If you are on the last page, the same thing happens for the "Next" and "Last" links..
There is only one issue that I have, and that is the "1 2 3 4" part. That is based on how many entries are in the table divided by how many items to list per page.
Anyways, if you have a lot of entries, say 1,000. You will get too many links like this: "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ....etc".
What I would like to do is keep it "clean". Displaying only 5 at a time with the "current" page in the middle:
So say you are on page 3. It would look like this.
First | Prev 1 2 3 4 5 Next | Last
If you're on page 7. It would look like this.
First | Prev 5 6 7 8 9 Next | Last
If anyone has "hints" please let me know, it's one of those things that you can either figure out in 5 minutes or it takes a day...I don't think it's hard, just a matter of "figuring" it out...but I know there are a lot of people here with "pagination" experience.
Also, PLEASE comment on my code, if you have suggestions to make it better, let me know, I won't be offended...
Just don't tell me to do it in OO because I'm still new to that and that will be my next project...
|
|
|
|
04-16-2009, 04:00 PM
|
#2 (permalink)
|
|
The Prestige
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
|
First off, why are you posting this in Script Giveaways if you need help with it?
Secondly, I see you still base your entire function on a database - which is fine - but not really good practice.
About your issue, you have to insert a new variable $span, and do some simple math logic to get around this. I would post my updated script, but it's entirely OOP so I'm not sure if that would actually do any help.
But like I said, you need to do some simple math.
Bascicly, what you wanna check for is if the pagenr(in your for-loop) is outside the span, and only display those who are in the span. By span, I mean the value of the variable $span, which would be an integer - corresponding to how many pages you want on each side of the current page.
Example: $span = 2
3 4 5 6 7
$span = 4
1 2 3 4 5 6 7 8 9
Here's the code to display the first link if the you're outside the span and above first page.
PHP Code:
// If the current page minus the span is larger than 1, it means that the first page is outside the span, and thus we want to // display it! if(($page[0] - $span) > 1) { echo '<a href="?page=1">First</a> '; // If the current page minus (span + 1) is larger than 1, it means that the first page is outside the span AND it is outside the // span with more than 1, and thus we want to add an extra ".." after the first link. if(($page[0] - ($span + 1)) > 1) { $firstlink .= '.. '; } }
$page[0] is the current pagenr.
__________________
|
|
|
|
04-16-2009, 04:59 PM
|
#3 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Quote:
Originally Posted by Tanax
First off, why are you posting this in Script Giveaways if you need help with it?
|
Yeah, I figured I would share what I have so far. I suppose I should have waited until the code is 100% complete to my liking.
Quote:
Originally Posted by Tanax
Secondly, I see you still base your entire function on a database - which is fine - but not really good practice.
|
Well I think this is POV, I'd like to get suggestions from others. I know good practice is to be as general as possible with the data so you can insert any type, (arrays, SQL, files/directories etc..) But you also have to remember I am a newbie...
Quote:
Originally Posted by Tanax
About your issue, you have to insert a new variable $span, and do some simple math logic to get around this. I would post my updated script, but it's entirely OOP so I'm not sure if that would actually do any help.
But like I said, you need to do some simple math.
Bascicly, what you wanna check for is if the pagenr(in your for-loop) is outside the span, and only display those who are in the span. By span, I mean the value of the variable $span, which would be an integer - corresponding to how many pages you want on each side of the current page.
Example: $span = 2
3 4 5 6 7
$span = 4
1 2 3 4 5 6 7 8 9
Here's the code to display the first link if the you're outside the span and above first page.
PHP Code:
// If the current page minus the span is larger than 1, it means that the first page is outside the span, and thus we want to
// display it!
if(($page[0] - $span) > 1) {
echo '<a href="?page=1">First</a> ';
// If the current page minus (span + 1) is larger than 1, it means that the first page is outside the span AND it is outside the
// span with more than 1, and thus we want to add an extra ".." after the first link.
if(($page[0] - ($span + 1)) > 1) {
$firstlink .= '.. ';
}
}
$page[0] is the current pagenr.
|
Thank you! I think I can figure it out now with "$span".
Let me get back to the grind and hopefully figure it out at some point today...
|
|
|
|
04-16-2009, 09:20 PM
|
#4 (permalink)
|
|
The Prestige
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
|
Quote:
Originally Posted by allworknoplay
Well I think this is POV, I'd like to get suggestions from others. I know good practice is to be as general as possible with the data so you can insert any type, (arrays, SQL, files/directories etc..) But you also have to remember I am a newbie...
Thank you! I think I can figure it out now with "$span".
Let me get back to the grind and hopefully figure it out at some point today...
|
What does POV mean? Yes of course, but remember - it's when you're a "newbie" that you learn the most, and if you practice the "wrong" way of stuff, you will have to struggle more to "unlearn" the "wrong" way, and learn the right way - if that makes any sense?
Post the progress you make!
__________________
|
|
|
|
04-17-2009, 04:41 PM
|
#5 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Ok, I have figured out the span issue. Here is how I am doing it.
As it loops through, it looks at the $get_page variable, and appends 2 pages before and after it and puts it into an array.
I've tested it and it works perfectly!
Code:
/* CREATE PAGES TO DISPLAY */
for ($i=1; $i<=$page_last; $i++) {
if(($get_page - 2) == $i) $display_pages[] = " <a href=\"$_SERVER[PHP_SELF]?p=$i\">$i</a>";
if(($get_page - 1) == $i) $display_pages[] = " <a href=\"$_SERVER[PHP_SELF]?p=$i\">$i</a>";
if($get_page == $i) $display_pages[] = "$i";
if(($get_page + 1) == $i) $display_pages[] = " <a href=\"$_SERVER[PHP_SELF]?p=$i\">$i</a>";
if(($get_page + 2) == $i) $display_pages[] = " <a href=\"$_SERVER[PHP_SELF]?p=$i\">$i</a>";
}
If $get_page = 10.
Then the output will be:
8 9 10 11 12
|
|
|
|
04-17-2009, 04:44 PM
|
#6 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Quote:
Originally Posted by Tanax
What does POV mean? Yes of course, but remember - it's when you're a "newbie" that you learn the most, and if you practice the "wrong" way of stuff, you will have to struggle more to "unlearn" the "wrong" way, and learn the right way - if that makes any sense?
Post the progress you make!
|
yes that makes sense. I definitley want to start off with the correct fundamentals because the last 10 years I've been hacking my way through programs.
The only issue is, I don't know of any other way of getting data other than using mySQL. What I mean by that is, if you were to tell me 2 or 3 other ways in which other people are getting data not using SQL, then I can look into making the function accept more generic attributes when calling the function so it would be more independent of databases....
POV = point of view
Take a look at my code I just posted that will span 2 elements to the right and left of the current page.
I'm positive that's not what you had in mind so if you have a better way, please let me know.
Of course with programming there are always 100 different ways to do things...but I would like your comments on my approach...
|
|
|
|
04-17-2009, 06:01 PM
|
#7 (permalink)
|
|
Moderateur
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
|
More ways of using MySQL other than the basic MySQL extension: - MySQL Improved
- PDO MySQL
More data stores other than MySQL:
Then there might be a time where you want to paginate something else entirely like existing PHP data (arrays, objects). In basic terms, pagination should be able to take a collection of things and break it down into paged sets. Those things needn't necessarily be database query results and the output needn't necessarily be HTML (or the exact HTML that your function uses).
|
|
|
|
04-17-2009, 06:12 PM
|
#8 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Quote:
Originally Posted by Salathe
In basic terms, pagination should be able to take a collection of things and break it down into paged sets. Those things needn't necessarily be database query results and the output needn't necessarily be HTML (or the exact HTML that your function uses).
|
Ohhh ok, that makes more sense. See, I always thought pagination was just your everyday navigation of HTML pages. I didn't know that it was more of an all around method of "flipping" through things....
That's why I couldn't see beyond using DB queries to build the navigation pages...
I have heard of mysqli, and PDO but never really looked into them, I'll take a peek now...
|
|
|
|
04-17-2009, 06:51 PM
|
#9 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Ok, I modified my function so that the DB query isn't within it. Now you have to do the DB query outside, then provide the results to the function. This SHOULD work for other types of data types correct?
You should be able to feed it results from other DB sources or feed it an array and it should still work....
Code:
/* QUERY TO GET TOTAL NUMBER OF ENTRIES FOR PAGINATE FUNCTION */
$query_total = "YOUR SELECT STATEMENT";
/* GET TOTAL NUMBER OF ENTRIES FIRST */
$results = mysql_query($query_total);
$totalrows = mysql_num_rows($results);
function pagination($get_page,$totalrows,$page_limit) {
/* SET SOME VARIABLES */
if(!$get_page) $p = 1;
if(!$display) $display = 5;
$page_next = ($get_page + 1);
$page_prev = ($get_page - 1);
/* CALCULATE LAST PAGE LINK */
/* THIS ALSO WILL BE USED IN THE FOR LOOP */
$page_last = ceil($totalrows/$page_limit);
/* USE $start VAR FOR DATABASE QUERY ex: LIMIT $start,$page_limit */
if($p == 1) $start = 0;
else $start = ($get_page - 1) * $page_limit;
/* CREATE OFFSET ex: 1 -25, 26 - 50 */
$starting_no = ($start +1);
/* CREATE ENDCOUNT ex: 1 - 25, THE 25 IS THE ENDCOUNT */
if (($totalrows - $start) < $page_limit) {
$end_count = $totalrows;
} elseif ($totalrows - $start >= $page_limit) {
$end_count = $start + $page_limit;
}
/* CREATE PAGES TO DISPLAY */
for ($i=1; $i<=$page_last; $i++) {
if(($get_page - 2) == $i) $display_pages[] = " <a href=\"$_SERVER[PHP_SELF]?p=$i\">$i</a>";
if(($get_page - 1) == $i) $display_pages[] = " <a href=\"$_SERVER[PHP_SELF]?p=$i\">$i</a>";
if($get_page == $i) $display_pages[] = "$i";
if(($get_page + 1) == $i) $display_pages[] = " <a href=\"$_SERVER[PHP_SELF]?p=$i\">$i</a>";
if(($get_page + 2) == $i) $display_pages[] = " <a href=\"$_SERVER[PHP_SELF]?p=$i\">$i</a>";
}
/* IF ON PAGE 1, UNLINK FIRST AND PREV LINKS */
if($get_page == 1) {
$first = "First";
$prev = "Prev";
}else{
$first = "<a href=\"$_SERVER[PHP_SELF]?p=1\">First</a>";
$prev = "<a href=\"$_SERVER[PHP_SELF]?p=$page_prev\">Prev</a>";
}
/* IF ON LAST PAGE, UNLINK LAST AND NEXT LINKS */
if($get_page == $page_last) {
$last = "Last";
$next = "Next";
}else{
$last = "<a href=\"$_SERVER[PHP_SELF]?p=$page_last\">Last</a>";
$next = "<a href=\"$_SERVER[PHP_SELF]?p=$page_next\">Next</a>";
}
return (array($first,$prev,$display_pages,$next,$last,$totalrows,$starting_no,$start,$page_limit,$end_count));
}###END FUNCTION
list($first,$prev,$display_pages,$next,$last,$totalrows,$starting_no,$start,$page_limit,$end_count) = pagination($_GET[p],$totalrows,$page_limit);
|
|
|
|
04-17-2009, 07:06 PM
|
#10 (permalink)
|
|
The Prestige
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
|
Quote:
Originally Posted by allworknoplay
Ok, I modified my function so that the DB query isn't within it. Now you have to do the DB query outside, then provide the results to the function. This SHOULD work for other types of data types correct?
You should be able to feed it results from other DB sources or feed it an array and it should still work....
Code:
/* QUERY TO GET TOTAL NUMBER OF ENTRIES FOR PAGINATE FUNCTION */
$query_total = "YOUR SELECT STATEMENT";
/* GET TOTAL NUMBER OF ENTRIES FIRST */
$results = mysql_query($query_total);
$totalrows = mysql_num_rows($results);
function pagination($get_page,$totalrows,$page_limit) {
/* SET SOME VARIABLES */
if(!$get_page) $p = 1;
if(!$display) $display = 5;
$page_next = ($get_page + 1);
$page_prev = ($get_page - 1);
/* CALCULATE LAST PAGE LINK */
/* THIS ALSO WILL BE USED IN THE FOR LOOP */
$page_last = ceil($totalrows/$page_limit);
/* USE $start VAR FOR DATABASE QUERY ex: LIMIT $start,$page_limit */
if($p == 1) $start = 0;
else $start = ($get_page - 1) * $page_limit;
/* CREATE OFFSET ex: 1 -25, 26 - 50 */
$starting_no = ($start +1);
/* CREATE ENDCOUNT ex: 1 - 25, THE 25 IS THE ENDCOUNT */
if (($totalrows - $start) < $page_limit) {
$end_count = $totalrows;
} elseif ($totalrows - $start >= $page_limit) {
$end_count = $start + $page_limit;
}
/* CREATE PAGES TO DISPLAY */
for ($i=1; $i<=$page_last; $i++) {
if(($get_page - 2) == $i) $display_pages[] = " <a href=\"$_SERVER[PHP_SELF]?p=$i\">$i</a>";
if(($get_page - 1) == $i) $display_pages[] = " <a href=\"$_SERVER[PHP_SELF]?p=$i\">$i</a>";
if($get_page == $i) $display_pages[] = "$i";
if(($get_page + 1) == $i) $display_pages[] = " <a href=\"$_SERVER[PHP_SELF]?p=$i\">$i</a>";
if(($get_page + 2) == $i) $display_pages[] = " <a href=\"$_SERVER[PHP_SELF]?p=$i\">$i</a>";
}
/* IF ON PAGE 1, UNLINK FIRST AND PREV LINKS */
if($get_page == 1) {
$first = "First";
$prev = "Prev";
}else{
$first = "<a href=\"$_SERVER[PHP_SELF]?p=1\">First</a>";
$prev = "<a href=\"$_SERVER[PHP_SELF]?p=$page_prev\">Prev</a>";
}
/* IF ON LAST PAGE, UNLINK LAST AND NEXT LINKS */
if($get_page == $page_last) {
$last = "Last";
$next = "Next";
}else{
$last = "<a href=\"$_SERVER[PHP_SELF]?p=$page_last\">Last</a>";
$next = "<a href=\"$_SERVER[PHP_SELF]?p=$page_next\">Next</a>";
}
return (array($first,$prev,$display_pages,$next,$last,$totalrows,$starting_no,$start,$page_limit,$end_count));
}###END FUNCTION
list($first,$prev,$display_pages,$next,$last,$totalrows,$starting_no,$start,$page_limit,$end_count) = pagination($_GET[p],$totalrows,$page_limit);
|
Ah, much better 
Now go learn OOP and build a class off of it 
__________________
|
|
|
|
04-17-2009, 07:08 PM
|
#11 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Quote:
Originally Posted by Tanax
Ah, much better 
Now go learn OOP and build a class off of it 
|
Thanks, I should be able to just take this function and convert it into OO.
I will try it out now, I know I will need your help, Salathe and anyone else that is around lately....
Of course I'll try to do it on my own AND I won't post it here until it's complete.
BTW: I printed out your pagination class, hopefully I can pick up some tips from it without copying it too much...
|
|
|
|
04-17-2009, 07:39 PM
|
#12 (permalink)
|
|
The Prestige
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
|
Just a tip, don't print anything in your class, only return values - never echo them out
__________________
|
|
|
|
04-17-2009, 07:45 PM
|
#13 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Quote:
Originally Posted by Tanax
Just a tip, don't print anything in your class, only return values - never echo them out
|
Good to know, thanks!
I am having a hard time transitioning the mental thought from procedural code to OO code...
I hope I can have enough done later today for you to take a look....
|
|
|
|
04-17-2009, 08:51 PM
|
#14 (permalink)
|
|
The Frequenter
Join Date: Sep 2007
Location: Denmark
Posts: 352
Thanks: 8
|
Just a little security tip; Remember to escape HTML characters when using $_SERVER['PHP_SELF'], as its not filtered and may contain input that can cause XSS
__________________
|
|
|
04-17-2009, 08:55 PM
|
#15 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Quote:
Originally Posted by Kalle
Just a little security tip; Remember to escape HTML characters when using $_SERVER['PHP_SELF'], as its not filtered and may contain input that can cause XSS
|
hmmm, I know how to escape user input with mysql_real_escape function, how do you escape $_SERVER['PHP_SELF']?
Is it with the mysql function too or is there a PHP function?
|
|
|
|
04-17-2009, 09:00 PM
|
#16 (permalink)
|
|
The Prestige
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
|
I think he's referring to this:
PHP Code:
htmlspecialchars($data); //or perhaps this: urlencode($data);
__________________
|
|
|
|
04-17-2009, 09:03 PM
|
#17 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Quote:
Originally Posted by Tanax
I think he's referring to this:
PHP Code:
htmlspecialchars($data);
//or perhaps this:
urlencode($data);
|
Ok so I should do this?
$current_page = htmlspecialchars($_SERVER['PHP_SELF']);
Also, I was just thinking, what if we were to define the PHP_SELF like this:
define(CURRENT_PAGE,$_SERVER['PHP_SELF']);
Is that not a good idea?
|
|
|
|
04-17-2009, 10:55 PM
|
#18 (permalink)
|
|
The Frequenter
Join Date: Sep 2007
Location: Denmark
Posts: 352
Thanks: 8
|
yes escape $_SERVER['PHP_SELF'] like: $_SERVER['PHP_SELF'] = htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES);
=)
__________________
|
|
|
|
The Following User Says Thank You to Kalle For This Useful Post:
|
|
04-17-2009, 10:59 PM
|
#19 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Quote:
Originally Posted by Kalle
yes escape $_SERVER['PHP_SELF'] like: $_SERVER['PHP_SELF'] = htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES);
=)
|
ahhh! thanks!
Quick question, how would I use this in a class?
In the HTML, I would do it the way you just wrote it:
$_SERVER['PHP_SELF'] = htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES);
But when including a class, do I have to do the same thing in the class?
$_SERVER['PHP_SELF'] = htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES);
Reason why I ask this is that in my class I am using $_SERVER['PHP_SELF'] so I want to make sure that is escaped too...
|
|
|
|
04-17-2009, 11:32 PM
|
#20 (permalink)
|
|
The Frequenter
Join Date: Sep 2007
Location: Denmark
Posts: 352
Thanks: 8
|
$_SERVER is a superglobal, that means when you update a value it will reflect all scopes:
PHP Code:
<?php
expose_phpself();
$_SERVER['PHP_SELF'] = '/this/is/a/custom/value';
expose_phpself();
function expose_phpself()
{
echo($_SERVER['PHP_SELF'] . PHP_EOL);
}
?>
(as if I understood your question correctly :))
__________________
|
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Hybrid Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|