So What I'm trying to do is create pagination, with a max of 5 pages showing. If there are only five pages that are returned from my MySQL statement, return the five pages. Otherwise, return 2 pages in each direction. So ideally, if I'm currently on page 1, it shows pages 1 2 3 4 5. If I am on page 5 and there are a max of 5 pages, show 1 2 3 4 5. If, however, I am on page 20, and there are 100 total, I would like to show 18 19 20 21 22. Any suggestions?
问题:
回答1:
Let's say you have a query that returns lots and lots of rows:
$query_results = array(...);
And you have a maximum limit to how many results show up on the page:
$results_per_page = 20;
Now, the total number of pages you will need is
$total_pages = ceil(count($query_results)/$results_per_page);
But now comes the tricky part; you need to know what page the user is on, and what results show up on that page. Say you determine page number through a simple GET variable:
yoursite.com/results.php?page=2
So page 1 corresponds to results 0 - 19, page 2 to 20 - 29, etc. Then, you can determine what results get shown there like this:
$page = min($_GET['page'], $total_pages); //ensures you never have an illegal page
$start_results = ($page - 1) * $results_per_page;
$results_on_page = array_slice($query_results, $start_results, $results_per_page);
Now you can display those in HTML however you want. But what about the links? You said you wanted two links in either direction, for a total of five links on the page.
$total_links = 5;
$pivot = floor($total_links / 2);
$leftmost = max(1, $page - $pivot);
$rightmost = min($total_pages, $page + $pivot);
$links = array();
for ($i = $leftmost; $i <= $rightmost; $i++) {
$links[] = "results.php?page=$i";
}
That will give you an array of links for you to display on your page. I'll leave that part up to you.
Now, this will work, but it will be extremely inefficient for large result sets, because all the processing and limiting happens after it comes back from the database. Therefore, you probably want to do that in your query. I'll leave that as an exercise to the reader, but here's a hint to get you started:
SELECT * FROM some_table LIMIT $results_per_page OFFSET ($page - 1) * $results_per_page
That being said, rolling your own code for something so mundane and common is a good learning experience, but rarely a good use of your time. If this is for any kind of professional work, consider using a pre-built library, like the PEAR pager or Zend Framework's Zend_Paginator library.
回答2:
For larger page counts, what you're suggesting makes it hard for a user to easily navigate to distant pages. Consider using the "logarithmic" technique described here, instead:
How to do page navigation for many, many pages? Logarithmic page navigation