 |
Account Login
|
 |
 |
Latest Articles
|
 |
 |
IRC Channel
|
 |
 |
Associates
|
 |
 |
Associates
|
 |
|
 |
 |
|
 |
01-11-2008, 03:53 PM
|
#1 (permalink)
|
|
The Prestige
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
|
Please review my pagination class
Hello!
I've made a pagination class.
At the moment, it only has the basic features:
-Display pagelinks
-Display nextpage link
-Display prevpage link
-Display "Page: <currentpage> of <totalpages>"
-Display results depending on which page
I'm just wondering what you think of it.
example.php
php Code:
<?php/** |||||||||||||||||||||||||||||||||||||||||| |||| @author Tanax |||| @copyright 2008 |||||||||||||||||||||||||||||||||||||||||| **/ include('pagination.php'); $p = $_GET[ 'p']; $max = 10; // Create the object and set some basic values. $pagination = new pagination (); $pagination-> setMax($max); // Get the total results, and then calculate how many pages that becomes based on how many results per page. $totSql = "SELECT * FROM `table`"; $totQuery = mysql_query($totSql) or die(mysql_error()); $totResults = mysql_fetch_array($totQuery); $totPages = $pagination-> getPages($totResults); // Set the current page, and get the first result on it. $first = $pagination-> setPage($p); // Get the results of the current page. $exSql = "SELECT * FROM `table` LIMIT $first, $max"; $exQuery = mysql_query($exSql) or die(mysql_error()); $exResults = mysql_fetch_array($exQuery); // Echo out the current page, and the total amount of pages. $page = $pagination-> getCurrentPage(); echo 'Page: '. $page[ 0]. ' of '. $page[ 1]; // Get previous page link, and check if it's valid. $prevLink = $p - 1; if($pagination-> checkLink($prevLink)) { echo 'Previous Page'; } // Print all the pages foreach($totPages as $pageNumber) { if($pageNumber == $p) { echo '<strong>'. $pageNumber. '</strong>'; } else { echo $pageNumber; } } // Get the next page link, and check if it's valid. $nextLink = $p + 1; if($pagination-> checkLink($nextLink)) { echo 'Next Page'; } // Echo the results... ?>
pagination.php
php Code:
<?php/** |||||||||||||||||||||||||||||||||||||||||| |||| @author Tanax |||| @copyright 2008 |||||||||||||||||||||||||||||||||||||||||| **/ class pagination { // The total value. private $totalPages; private $totalResults; private $totalPerPage; // The current value. private $currentPage; private $currentSpan; private $firstResult; public function setMax ($max) { if(is_numeric($max)) { $this-> totalPerPage = $max; } } public function setPage ($page) { if(is_numeric($page)) { $this-> currentPage = mysql_real_escape_string($page); $this-> firstResult = (($this-> currentPage * $this-> totalPerPage) - $this-> totalPerPage); return $this-> firstResult; } } public function getPages ($results) { $this-> totalResults = count($results); $totalPages = $this-> totalResults / $this-> totalPerPage; $this-> totalPages = ceil($totalPages); $x = 1; $array = array(); while($x <= $this-> totalPages) { $array[] = $x; $x++; } return $array; } public function checkLink ($pagenr) { if($pagenr <= $this-> totalPages && $pagenr >= 1) { return true; } return false; } public function getCurrentPage () { $array = array(); $array[] = $this-> currentPage; $array[] = $this-> totalPages; return $array; } }?>
Yes, I know I didn't comment the functions inside the class. But meh, too lazy atm. Besides, I commented when calling the functions in example.php.
Anyhow!
What do you think of it?
Also.. how would I add the functionality for a span.
So it only displays the pagelinks within the set span.
".. 5 6 7 8 9 ..."
If the span was set to 2(2 at each direction).
Please comment 
|
|
|
|
01-11-2008, 04:22 PM
|
#2 (permalink)
|
|
The Addict
Join Date: Jan 2008
Location: USA
Posts: 217
Thanks: 16
|
Your class looks good and functional, but I think I see a few potential trip-wires.
The problems I see aren't related to your object, but your queries. For instance, it'd be better to query:
sql Code:
SELECT COUNT(*) AS `count` FROM `table`
Otherwise you are getting every single row from the database to walk through to find the count. On a table with lots of rows this'd take quite some time.
This would necessitate a slight change in how you assign the page count and limit modulo.
If you were to improve the object itself, I'd suggest that: you make it independent of the data passed, and that its output can handle "first prev ... 1 2 3 4 5 ... next last" as an option. From there the only thing to change is the number of rows on a page, and localization support. Then you'd never need to write another one again! 
__________________
Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning. - Rich Cook
|
|
|
|
01-11-2008, 04:24 PM
|
#3 (permalink)
|
|
The Frequenter
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 438
Thanks: 3
|
Quote:
Originally Posted by Tanax
Also.. how would I add the functionality for a span.
So it only displays the pagelinks within the set span.
".. 5 6 7 8 9 ..."
If the span was set to 2(2 at each direction).
|
Sorry about not commenting on your class, I'm just too lazy to read the whole code right now :D For the matter quoted above, you would have to loop a little each side of the current page ('span' times). That's how I did it for myself, however. If you find a better alternative, please share.
__________________
I have optimistic thoughts, even though sometimes (if not always) life's a bitch.
|
|
|
|
01-11-2008, 04:36 PM
|
#4 (permalink)
|
|
The Addict
Join Date: Jan 2008
Location: USA
Posts: 217
Thanks: 16
|
Missed your request Tanax and went right to the issue I saw, apologies.
A way would be to use a function/method like this:
PHP Code:
function showPages($current, $span = 2) { $leftMost = $current - $span; echo 'First ... '; while($leftMost <= $current+$span) { $tag = ($leftMost == $current) ? 'b' : 'span'; echo "<$tag>$leftMost</$tag> "; $leftMost++; } echo '... Last'; }
Yields (on a span of 3):
Quote:
|
First ... 5 6 7 8 9 10 11 ... Last
|
You'll have to tweak it to not get a negative number when on the first page. However, I figured that I'd leave you with the concept. 
__________________
Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning. - Rich Cook
|
|
|
|
01-11-2008, 04:56 PM
|
#5 (permalink)
|
|
The Prestige
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
|
@RobertK 1st Post- So.. what exactly is it better for? :-S
And what do you mean with that it should handle "first prev ... 1 2 3 4 5 ... next last" as an option? :O
@xenon- Yah, I did it before too, with loops on each side(see my gallery script that I released somewhere here..). I was just wondering how it would be solved in this case, and if it exists any easier way of accomplishing it.
@RobertK 2nd Post- Yah, that's almost exactly how I did it before, but it's quite annoying piece of code, and I was just wondering if there are any easier way xD
But thanks 
|
|
|
|
01-11-2008, 05:48 PM
|
#6 (permalink)
|
|
The Addict
Join Date: Jan 2008
Location: USA
Posts: 217
Thanks: 16
|
Quote:
Originally Posted by Tanax
@RobertK 1st Post- So.. what exactly is it better for? :-S
|
You're getting the count of the rows with my query, instead of getting all rows to count (with the object) and then query again for the your portion shown by the page. This change from selecting all rows, and the megs of data it might entail, to selecting just the count of the rows gives a speed increase.
Quote:
Originally Posted by Tanax
And what do you mean with that it should handle "first prev ... 1 2 3 4 5 ... next last" as an option? :O
|
It should be able to handle localization, other languages, and the option to include or exclude first/last/next/prev page links. Just further options you can bind into one class easily.
Quote:
Originally Posted by Tanax
@RobertK 2nd Post- Yah, that's almost exactly how I did it before, but it's quite annoying piece of code, and I was just wondering if there are any easier way xD
But thanks 
|
Not really. I know no other ways.
__________________
Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning. - Rich Cook
|
|
|
|
01-11-2008, 11:29 PM
|
#7 (permalink)
|
|
The Prestige
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
|
About language support..
This is a pagination class... not a complete SYSTEM
I will just have to use a language class, and then get the correct words..
That's why I in this pagination class just return raw data, and all the text are outputted outside of the class.
And if I wish to have the "option" to remove the prev link, then I'll just delete that part from example.php where it outputs the link...
|
|
|
|
01-11-2008, 11:33 PM
|
#8 (permalink)
|
|
The Addict
Join Date: Jan 2008
Location: USA
Posts: 217
Thanks: 16
|
As I said,
Quote:
|
From there the only thing to change is the number of rows on a page, and localization support. Then you'd never need to write another one again!
|
It was only a statement of, "this is as far as you can go."
Nothing more.
__________________
Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning. - Rich Cook
|
|
|
|
01-12-2008, 12:07 AM
|
#9 (permalink)
|
|
The Prestige
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
|
Ahh, okey
But outputting text, or HTML within a class method, kind of destroys the purpose with classes; being able to create classes that can be used on ANY website, so people just download the core, and they build the user-side themselves 
|
|
|
|
01-12-2008, 12:10 AM
|
#10 (permalink)
|
|
The Addict
Join Date: Jan 2008
Location: USA
Posts: 217
Thanks: 16
|
Well, I never specified what or how it output, just that it should. I personally wouldn't have it directly set HTML either, that's for template engines, etc.
__________________
Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning. - Rich Cook
|
|
|
|
03-23-2009, 04:14 PM
|
#11 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Quote:
Originally Posted by RobertK
Your class looks good and functional, but I think I see a few potential trip-wires.
The problems I see aren't related to your object, but your queries. For instance, it'd be better to query:
sql Code:
SELECT COUNT(*) AS `count` FROM `table`
Otherwise you are getting every single row from the database to walk through to find the count. On a table with lots of rows this'd take quite some time.
|
Hopefully Tanax or someone else can answer this. I don't know if RobertK is still around? Anyways, this is more of a SQL question.
The way I count rows has always been this:
$query = "SELECT `table_id` FROM table";
$num_count = mysql_num_rows($query);
Then use the $num_count in my various loops...mainly "for" loops.
Anyways, what I read was never to use wildcard "*" because you only want the count, and you don't want to select every column in a table especially if it's huge. So that's why I pick the `table_id`, it can really be any column.
So according to RobertK's post, is there a BETTER way to get the number of rows in a table that is less resource intensive?
What is the fundamental significance of:
SELECT COUNT(*) AS `count` FROM `table`
I know this is an old post, sorry, I just felt like searching pagination and I found this thread...
|
|
|
|
03-23-2009, 05:12 PM
|
#12 (permalink)
|
|
The Frequenter
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 438
Thanks: 3
|
Well, selecting all columns, as well as selecting just one column for counting will always be extremely slow because the MySQL engine should go through each and every one of the rows in that table and get the requested data for you, where as select count(*) will determine the number of entries based on the metadata extracted from the index keys. It just performs a lookup, instead of reading every actual row from the db. I hope you understand the whole difference. If not, ask more :)
__________________
I have optimistic thoughts, even though sometimes (if not always) life's a bitch.
|
|
|
|
|
The Following User Says Thank You to xenon For This Useful Post:
|
|
03-23-2009, 05:51 PM
|
#13 (permalink)
|
|
The Gregarious
Join Date: Feb 2009
Location: New York
Posts: 645
Thanks: 64
|
Quote:
Originally Posted by xenon
Well, selecting all columns, as well as selecting just one column for counting will always be extremely slow because the MySQL engine should go through each and every one of the rows in that table and get the requested data for you, where as select count(*) will determine the number of entries based on the metadata extracted from the index keys. It just performs a lookup, instead of reading every actual row from the db. I hope you understand the whole difference. If not, ask more :)
|
Ok gotchya. Yes I understand now. I will attempt to use this for future purposes as best practice.
|
|
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Linear 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
|
|
|
|