timefrontiers/php-pagination
最新稳定版本:v1.0.0
Composer 安装命令:
composer require timefrontiers/php-pagination
包简介
PHP pagination trait for database objects and collections
README 文档
README
Lightweight PHP pagination trait for database objects and collections.
Installation
composer require timefrontiers/php-pagination
Quick Start
use TimeFrontiers\Helper\Pagination; class UserRepository { use Pagination; public function getUsers():array { // Set pagination from request (?page=2&per_page=25) $this->fromRequest(); // Get total count $this->setTotalCount($this->countAll()); // Query with pagination $sql = "SELECT * FROM users {$this->limitClause()}"; return $this->query($sql); } } $repo = new UserRepository(); $users = $repo->getUsers(); // Display info echo "Page {$repo->currentPage()} of {$repo->totalPages()}"; echo "Showing {$repo->itemStart()}-{$repo->itemEnd()} of {$repo->totalCount()}";
Usage with DatabaseObject
use TimeFrontiers\Helper\DatabaseObject; use TimeFrontiers\Helper\Pagination; class User { use DatabaseObject, Pagination; protected static string $_table_name = 'users'; } // In controller $user = new User(); $user->fromRequest()->setTotalCount(User::countAll()); $users = User::findBySql( "SELECT * FROM users ORDER BY created_at DESC {$user->limitClause()}" ); // Pass pagination to view $pagination = $user->paginationToArray();
Configuration
Set Page
$this->setPage(3); // Go to page 3 $this->setPerPage(50); // 50 items per page $this->setTotalCount(1000); // 1000 total items
From Request
// Uses $_GET['page'] and $_GET['per_page'] $this->fromRequest(); // Custom parameter names $this->fromRequest('p', 'limit', 25); // Uses $_GET['p'] for page, $_GET['limit'] for per_page, default 25
Getters
$this->currentPage(); // int: Current page number $this->perPage(); // int: Items per page $this->totalCount(); // int: Total items $this->totalPages(); // int: Total pages $this->offset(); // int: SQL OFFSET value
Navigation
$this->previousPage(); // int: Previous page number $this->nextPage(); // int: Next page number $this->hasPreviousPage(); // bool: Has previous? $this->hasNextPage(); // bool: Has next? $this->isFirstPage(); // bool: On first page? $this->isLastPage(); // bool: On last page?
Item Range
// Page 2, 20 per page, 95 total items $this->itemStart(); // 21 $this->itemEnd(); // 40 $this->itemRange(); // [21, 40] // "Showing 21-40 of 95 results" echo "Showing {$this->itemStart()}-{$this->itemEnd()} of {$this->totalCount()} results";
State Checks
$this->isEmpty(); // bool: No results? $this->isNotEmpty(); // bool: Has results? $this->hasPages(); // bool: More than 1 page? $this->isValidPage(5); // bool: Is page 5 valid?
SQL Helpers
// LIMIT clause $sql = "SELECT * FROM users {$this->limitClause()}"; // "SELECT * FROM users LIMIT 20 OFFSET 40" // As array $limit = $this->limitOffset(); // ['limit' => 20, 'offset' => 40]
Page Range for UI
// Generate page numbers for pagination UI // Current page: 5, Total: 20 $pages = $this->pageRange(2); // [1, null, 3, 4, 5, 6, 7, null, 20] // null = ellipsis (...) // Render pagination foreach ($this->pageRange(2) as $page) { if ($page === null) { echo '<span>...</span>'; } else { $active = $page === $this->currentPage() ? 'active' : ''; echo "<a href='?page={$page}' class='{$active}'>{$page}</a>"; } } // Get all pages (no ellipsis) $this->pages(); // [1, 2, 3, 4, 5, ...]
URL Helpers
// Build URL for specific page $this->pageUrl(3); // "/users?page=3&search=john" // Previous/Next URLs $this->previousPageUrl(); // "/users?page=1" or null $this->nextPageUrl(); // "/users?page=3" or null // Custom base URL $this->pageUrl(5, '/api/users', 'p'); // "/api/users?p=5"
API Response
// Basic metadata $meta = $this->paginationToArray(); /* [ 'current_page' => 2, 'per_page' => 20, 'total' => 95, 'total_pages' => 5, 'from' => 21, 'to' => 40, 'has_more' => true, 'is_first_page' => false, 'is_last_page' => false, ] */ // With links $meta = $this->paginationMeta('/api/users'); /* [ 'current_page' => 2, ... 'links' => [ 'first' => '/api/users?page=1', 'last' => '/api/users?page=5', 'prev' => '/api/users?page=1', 'next' => '/api/users?page=3', ] ] */ // API response return [ 'data' => $users, 'meta' => $this->paginationMeta(), ];
Complete Example
Repository Pattern
class ArticleRepository { use Pagination; private PDO $db; public function __construct(PDO $db) { $this->db = $db; } public function getPaginated(array $filters = []):array { // Configure from request $this->fromRequest(); // Build query $where = $this->buildWhere($filters); // Get total count $countSql = "SELECT COUNT(*) FROM articles {$where}"; $total = $this->db->query($countSql)->fetchColumn(); $this->setTotalCount((int)$total); // Get paginated results $sql = "SELECT * FROM articles {$where} ORDER BY created_at DESC {$this->limitClause()}"; $articles = $this->db->query($sql)->fetchAll(); return [ 'data' => $articles, 'meta' => $this->paginationToArray(), ]; } }
Controller
$repo = new ArticleRepository($pdo); $result = $repo->getPaginated(['status' => 'published']); // JSON API header('Content-Type: application/json'); echo json_encode($result);
Blade-style View
<!-- Results info --> <p> Showing <?= $pagination->itemStart() ?>-<?= $pagination->itemEnd() ?> of <?= $pagination->totalCount() ?> results </p> <!-- Pagination links --> <nav> <?php if ($pagination->hasPreviousPage()): ?> <a href="<?= $pagination->previousPageUrl() ?>">← Previous</a> <?php endif; ?> <?php foreach ($pagination->pageRange(2) as $page): ?> <?php if ($page === null): ?> <span>...</span> <?php else: ?> <a href="<?= $pagination->pageUrl($page) ?>" class="<?= $page === $pagination->currentPage() ? 'active' : '' ?>"> <?= $page ?> </a> <?php endif; ?> <?php endforeach; ?> <?php if ($pagination->hasNextPage()): ?> <a href="<?= $pagination->nextPageUrl() ?>">Next →</a> <?php endif; ?> </nav>
Method Reference
Setters
| Method | Description |
|---|---|
setPage(int $page) |
Set current page |
setPerPage(int $per_page) |
Set items per page (1-1000) |
setTotalCount(int $count) |
Set total item count |
fromRequest($page_key, $per_page_key, $default) |
Load from $_GET |
Getters
| Method | Returns | Description |
|---|---|---|
currentPage() |
int |
Current page number |
perPage() |
int |
Items per page |
totalCount() |
int |
Total items |
totalPages() |
int |
Total pages |
offset() |
int |
SQL OFFSET value |
previousPage() |
int |
Previous page number |
nextPage() |
int |
Next page number |
itemStart() |
int |
First item number on page |
itemEnd() |
int |
Last item number on page |
itemRange() |
array |
[start, end] |
Checks
| Method | Returns | Description |
|---|---|---|
isEmpty() |
bool |
No results |
isNotEmpty() |
bool |
Has results |
hasPages() |
bool |
Multiple pages exist |
hasPreviousPage() |
bool |
Previous page exists |
hasNextPage() |
bool |
Next page exists |
isFirstPage() |
bool |
On first page |
isLastPage() |
bool |
On last page |
isValidPage(int) |
bool |
Page number is valid |
SQL & URLs
| Method | Returns | Description |
|---|---|---|
limitClause() |
string |
"LIMIT X OFFSET Y" |
limitOffset() |
array |
['limit' => X, 'offset' => Y] |
pageUrl(int, ?string, string) |
string |
URL for page |
previousPageUrl() |
?string |
Previous page URL |
nextPageUrl() |
?string |
Next page URL |
pageRange(int) |
array |
Page numbers with ellipsis |
pages() |
array |
All page numbers |
Export
| Method | Returns | Description |
|---|---|---|
paginationToArray() |
array |
Pagination metadata |
paginationMeta(?string, string) |
array |
Metadata with links |
License
MIT
统计信息
- 总下载量: 11
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 4
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-04-16