Pagination
Introductionβ
Pagination is an essential feature for displaying large amounts of data in an organized way. BowPHP provides a powerful and flexible Pagination class that makes it easy to navigate through database query results.
Basic usageβ
paginate signatureβ
paginate(int $per_page, int $current = 0, ?int $chunk = null): Pagination
| Parameter | Type | Description |
|---|---|---|
per_page | int | Number of items per page. |
current | int | Requested page number (1-indexed). 0 is normalized to 1. |
chunk | ?int | If set, the returned collection is split into sub-arrays of this size. |
Pagination with the Query Builderβ
You can paginate Query Builder results using the paginate method:
use Bow\Database\Database;
$users = Database::table('users')->paginate(15);
// Specific page
$users = Database::table('users')->paginate(15, $request->get('page', 1));
Pagination with modelsβ
With the Barry ORM, pagination is just as simple:
use App\Models\User;
$users = User::paginate(15);
$users = User::paginate(15, 2); // Page 2
Pagination with conditionsβ
You can combine pagination with query conditions:
use App\Models\User;
$users = User::where('status', 'active')
->orderBy('created_at', 'desc')
->paginate(10);
Navigation methodsβ
The Pagination class provides several methods for navigating between pages:
Information about the current pageβ
use App\Models\User;
$pagination = User::paginate(15);
// Get the current page number
$pagination->current(); // e.g. 2
// Get the number of items per page
$pagination->perPage(); // e.g. 15
// Get the total number of items
$pagination->total(); // e.g. 150
// Get the total number of pages
$pagination->totalPages(); // e.g. 10
Navigation between pagesβ
// Get the next page number (0 on the last page)
$pagination->next(); // e.g. 3
// Check whether there is a next page
$pagination->hasNext(); // true or false
// Get the previous page number
$pagination->previous(); // e.g. 1
// Check whether there is a previous page
$pagination->hasPrevious(); // true or false
hasPrevious() on the first pageOn page 1, previous() returns 1 (not 0), which means that
hasPrevious() returns true β it only signals that a "previous" page
number is available, not that there is actually a page before the current
one.
To decide whether to display a "Previous" link in a view, prefer
onFirstPage():
if (!$pagination->onFirstPage()) {
// Display the Previous link
}
The same logic applies on the right side: hasNext() is reliable, but
onLastPage() is often more expressive in a template.
Position checksβ
// Check whether we are on the first page
$pagination->onFirstPage(); // true or false
// Check whether we are on the last page
$pagination->onLastPage(); // true or false
// Check whether there are multiple pages
$pagination->hasPages(); // true or false
Accessing the dataβ
Retrieving itemsβ
// Get the collection of items for the current page
$items = $pagination->items();
foreach ($items as $item) {
echo $item->name;
}
Information about the itemsβ
// Number of items on the current page
$pagination->count(); // e.g. 15
// Check whether the pagination is empty
$pagination->isEmpty(); // true or false
// Check whether the pagination contains items
$pagination->isNotEmpty(); // true or false
// Index of the first item (1-indexed)
$pagination->firstItem(); // e.g. 16 (on page 2 with 15 per page)
// Index of the last item (1-indexed)
$pagination->lastItem(); // e.g. 30
Array accessβ
The Pagination class implements ArrayAccess, which lets you access items like an array:
// Access an item by its index
$firstUser = $pagination[0];
// Check whether an index exists
if (isset($pagination[0])) {
// ...
}
Iterationβ
You can iterate directly over the pagination object:
foreach ($pagination as $user) {
echo $user->name;
}
Generating URLsβ
The Pagination class can generate URLs for navigation.
Configuring the base URLβ
$pagination->setBaseUrl('https://example.com/users');
Customizing the page parameterβ
By default, the page parameter is page. You can customize it:
$pagination->setPageParam('p');
// Will generate URLs like: https://example.com/users?p=2
Adding query parametersβ
// Add parameters (keeps existing ones)
$pagination->withQueryParams(['sort' => 'name', 'order' => 'asc']);
// Replace all parameters
$pagination->setQueryParams(['filter' => 'active']);
Reading the current configurationβ
Three getters let you retrieve the current URL configuration β useful for debugging or to read the configuration back in a shared view:
$pagination->getBaseUrl(); // 'https://example.com/users' or null
$pagination->getPageParam(); // 'page' (or the value set via setPageParam)
$pagination->getQueryParams(); // ['sort' => 'name', 'order' => 'asc']
Generating URLsβ
// URL for a specific page
$pagination->url(3); // https://example.com/users?page=3
// URL of the next page
$pagination->nextPageUrl(); // https://example.com/users?page=3
// URL of the previous page
$pagination->previousPageUrl(); // https://example.com/users?page=1
// URL of the first page
$pagination->firstPageUrl(); // https://example.com/users?page=1
// URL of the last page
$pagination->lastPageUrl(); // https://example.com/users?page=10
URL rangeβ
You can obtain an array of URLs for a range of pages around the current page:
// Get the URLs for 3 pages on each side of the current page
$urls = $pagination->getUrlRange(3);
// [
// 2 => 'https://example.com/users?page=2',
// 3 => 'https://example.com/users?page=3',
// 4 => 'https://example.com/users?page=4', // current page
// 5 => 'https://example.com/users?page=5',
// 6 => 'https://example.com/users?page=6',
// ]
Pagination linksβ
The links() method generates a complete array of data for rendering the pagination:
$links = $pagination->links(2); // 2 pages on each side
Each element of the array contains:
url: The page URL (ornull)label: The text to displayactive: Whether it is the current pagedisabled: Whether the link is disabled
Example resultβ
[
['url' => 'https://...?page=1', 'label' => 'Β« Previous', 'active' => false, 'disabled' => false],
['url' => 'https://...?page=1', 'label' => '1', 'active' => false, 'disabled' => false],
['url' => null, 'label' => '...', 'active' => false, 'disabled' => true],
['url' => 'https://...?page=4', 'label' => '4', 'active' => false, 'disabled' => false],
['url' => 'https://...?page=5', 'label' => '5', 'active' => true, 'disabled' => false],
['url' => 'https://...?page=6', 'label' => '6', 'active' => false, 'disabled' => false],
['url' => null, 'label' => '...', 'active' => false, 'disabled' => true],
['url' => 'https://...?page=10', 'label' => '10', 'active' => false, 'disabled' => false],
['url' => 'https://...?page=6', 'label' => 'Next Β»', 'active' => false, 'disabled' => false],
]
Serializationβ
Converting to an arrayβ
$array = $pagination->toArray();
// [
// 'current_page' => 2,
// 'data' => [...],
// 'first_item' => 16,
// 'last_item' => 30,
// 'per_page' => 15,
// 'total' => 150,
// 'total_pages' => 10,
// 'next_page' => 3,
// 'previous_page' => 1,
// ]
Converting to JSONβ
$json = $pagination->toJson();
// With formatting options
$json = $pagination->toJson(JSON_PRETTY_PRINT);
Displaying in viewsβ
With Tintin (template engine)β
<div class="container">
<!-- Display the items -->
%foreach($users as $user)
<div class="user">
{{ $user->name }}
</div>
%endforeach
<!-- Pagination navigation -->
%if($users->hasPages())
<nav class="pagination">
<!-- Previous button (we use onFirstPage to avoid a link to
the current page: hasPrevious() stays true on page 1, see Note above). -->
%if(!$users->onFirstPage())
<a href="{{ $users->previousPageUrl() }}">Β« Previous</a>
%else
<span class="disabled">Β« Previous</span>
%endif
<!-- Page links -->
%foreach($users->links() as $link)
%if($link['disabled'])
<span class="disabled">{{ $link['label'] }}</span>
%elseif($link['active'])
<span class="active">{{ $link['label'] }}</span>
%else
<a href="{{ $link['url'] }}">{{ $link['label'] }}</a>
%endif
%endforeach
<!-- Next button -->
%if(!$users->onLastPage())
<a href="{{ $users->nextPageUrl() }}">Next Β»</a>
%else
<span class="disabled">Next Β»</span>
%endif
</nav>
%endif
</div>
Pagination informationβ
<p>
Showing {{ $users->firstItem() }} to {{ $users->lastItem() }}
of {{ $users->total() }} results
</p>
Complete exampleβ
Controllerβ
namespace App\Http\Controllers;
use App\Models\User;
use Bow\Http\Request;
class UserController
{
public function index(Request $request)
{
$perPage = $request->get('per_page', 15);
$search = $request->get('search');
$query = User::query();
if ($search) {
$query->where('name', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%");
}
$users = $query->orderBy('name')->paginate($perPage);
// Configure the pagination URLs
$users->setBaseUrl(url('/users'))
->withQueryParams([
'search' => $search,
'per_page' => $perPage,
]);
return view('users.index', compact('users', 'search'));
}
}
Routeβ
$app->get('/users', 'UserController::index');
Is something missing?
If you run into problems with the documentation or have suggestions to improve the documentation or the project in general, please open an issue for us, or send a tweet mentioning the Twitter account @bowframework or directly on github.