Pagination
Introduction​
La pagination est une fonctionnalité essentielle pour afficher de grandes quantités de données de manière organisée. BowPHP fournit une classe Pagination puissante et flexible qui facilite la navigation à travers les résultats de requêtes de base de données.
Utilisation de base​
Signature de paginate​
paginate(int $per_page, int $current = 0, ?int $chunk = null): Pagination
| Paramètre | Type | Description |
|---|---|---|
per_page | int | Nombre d'éléments par page. |
current | int | Numéro de la page demandée (1-indexé). 0 est normalisé en 1. |
chunk | ?int | Si défini, la collection retournée est découpée en sous-tableaux de cette taille. |
Pagination avec Query Builder​
Vous pouvez paginer les résultats du Query Builder en utilisant la méthode paginate :
use Bow\Database\Database;
$users = Database::table('users')->paginate(15);
// Page spécifique
$users = Database::table('users')->paginate(15, $request->get('page', 1));
Pagination avec les modèles​
Avec l'ORM Barry, la pagination est tout aussi simple :
use App\Models\User;
$users = User::paginate(15);
$users = User::paginate(15, 2); // Page 2
Pagination avec des conditions​
Vous pouvez combiner la pagination avec des conditions de requĂŞte :
use App\Models\User;
$users = User::where('status', 'active')
->orderBy('created_at', 'desc')
->paginate(10);
Méthodes de navigation​
La classe Pagination fournit plusieurs méthodes pour naviguer entre les pages :
Informations sur la page courante​
use App\Models\User;
$pagination = User::paginate(15);
// Obtenir le numéro de la page courante
$pagination->current(); // Ex: 2
// Obtenir le nombre d'éléments par page
$pagination->perPage(); // Ex: 15
// Obtenir le nombre total d'éléments
$pagination->total(); // Ex: 150
// Obtenir le nombre total de pages
$pagination->totalPages(); // Ex: 10
Navigation entre les pages​
// Obtenir le numéro de la page suivante (0 sur la dernière page)
$pagination->next(); // Ex: 3
// Vérifier s'il y a une page suivante
$pagination->hasNext(); // true ou false
// Obtenir le numéro de la page précédente
$pagination->previous(); // Ex: 1
// Vérifier s'il y a une page précédente
$pagination->hasPrevious(); // true ou false
hasPrevious() sur la première pageSur la page 1, previous() retourne 1 (et non 0), ce qui fait que
hasPrevious() retourne true — il signale uniquement qu'un numéro de
page « précédent » est disponible, pas qu'il y a réellement une page avant
la courante.
Pour décider si afficher un lien « Précédent » dans une vue, préférez
onFirstPage() :
if (!$pagination->onFirstPage()) {
// Afficher le lien Précédent
}
Même logique côté droit : hasNext() est fiable, mais onLastPage() est
souvent plus expressif dans un template.
Vérifications de position​
// Vérifier si on est sur la première page
$pagination->onFirstPage(); // true ou false
// Vérifier si on est sur la dernière page
$pagination->onLastPage(); // true ou false
// Vérifier s'il y a plusieurs pages
$pagination->hasPages(); // true ou false
Accéder aux données​
Récupérer les éléments​
// Obtenir la collection des éléments de la page courante
$items = $pagination->items();
foreach ($items as $item) {
echo $item->name;
}
Informations sur les éléments​
// Nombre d'éléments sur la page courante
$pagination->count(); // Ex: 15
// Vérifier si la pagination est vide
$pagination->isEmpty(); // true ou false
// Vérifier si la pagination contient des éléments
$pagination->isNotEmpty(); // true ou false
// Index du premier élément (1-indexed)
$pagination->firstItem(); // Ex: 16 (sur la page 2 avec 15 par page)
// Index du dernier élément (1-indexed)
$pagination->lastItem(); // Ex: 30
Accès par tableau​
La classe Pagination implémente ArrayAccess, ce qui vous permet d'accéder aux éléments comme un tableau :
// Accéder à un élément par son index
$firstUser = $pagination[0];
// Vérifier si un index existe
if (isset($pagination[0])) {
// ...
}
Itération​
Vous pouvez itérer directement sur l'objet pagination :
foreach ($pagination as $user) {
echo $user->name;
}
Génération d'URLs​
La classe Pagination permet de générer des URLs pour la navigation.
Configuration de l'URL de base​
$pagination->setBaseUrl('https://example.com/users');
Personnalisation du paramètre de page​
Par défaut, le paramètre de page est page. Vous pouvez le personnaliser :
$pagination->setPageParam('p');
// Génèrera des URLs comme: https://example.com/users?p=2
Ajout de paramètres de requête​
// Ajouter des paramètres (conserve les existants)
$pagination->withQueryParams(['sort' => 'name', 'order' => 'asc']);
// Remplacer tous les paramètres
$pagination->setQueryParams(['filter' => 'active']);
Lecture de la configuration courante​
Trois getters permettent de récupérer la configuration URL actuelle — utile pour le debug ou pour relire la configuration dans une vue partagée :
$pagination->getBaseUrl(); // 'https://example.com/users' ou null
$pagination->getPageParam(); // 'page' (ou la valeur définie via setPageParam)
$pagination->getQueryParams(); // ['sort' => 'name', 'order' => 'asc']
Génération d'URLs​
// URL pour une page spécifique
$pagination->url(3); // https://example.com/users?page=3
// URL de la page suivante
$pagination->nextPageUrl(); // https://example.com/users?page=3
// URL de la page précédente
$pagination->previousPageUrl(); // https://example.com/users?page=1
// URL de la première page
$pagination->firstPageUrl(); // https://example.com/users?page=1
// URL de la dernière page
$pagination->lastPageUrl(); // https://example.com/users?page=10
Plage d'URLs​
Vous pouvez obtenir un tableau d'URLs pour une plage de pages autour de la page courante :
// Obtenir les URLs pour 3 pages de chaque côté de la page courante
$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', // page courante
// 5 => 'https://example.com/users?page=5',
// 6 => 'https://example.com/users?page=6',
// ]
Liens de pagination​
La méthode links() génère un tableau complet de données pour le rendu de la pagination :
$links = $pagination->links(2); // 2 pages de chaque côté
Chaque élément du tableau contient :
url: L'URL de la page (ounull)label: Le texte à afficheractive: Si c'est la page courantedisabled: Si le lien est désactivé
Exemple de résultat​
[
['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],
]
Sérialisation​
Conversion en tableau​
$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,
// ]
Conversion en JSON​
$json = $pagination->toJson();
// Avec options de formatage
$json = $pagination->toJson(JSON_PRETTY_PRINT);
Affichage dans les vues​
Avec Tintin (moteur de template)​
<div class="container">
<!-- Afficher les éléments -->
%foreach($users as $user)
<div class="user">
{{ $user->name }}
</div>
%endforeach
<!-- Navigation de pagination -->
%if($users->hasPages())
<nav class="pagination">
<!-- Bouton précédent (on utilise onFirstPage pour éviter un lien vers
soi-mĂŞme : hasPrevious() reste true sur la page 1, voir Note plus haut). -->
%if(!$users->onFirstPage())
<a href="{{ $users->previousPageUrl() }}">« Précédent</a>
%else
<span class="disabled">« Précédent</span>
%endif
<!-- Liens des pages -->
%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
<!-- Bouton suivant -->
%if(!$users->onLastPage())
<a href="{{ $users->nextPageUrl() }}">Suivant »</a>
%else
<span class="disabled">Suivant »</span>
%endif
</nav>
%endif
</div>
Informations de pagination​
<p>
Affichage de {{ $users->firstItem() }} Ă {{ $users->lastItem() }}
sur {{ $users->total() }} résultats
</p>
Exemple complet​
Contrôleur​
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);
// Configurer les URLs de pagination
$users->setBaseUrl(url('/users'))
->withQueryParams([
'search' => $search,
'per_page' => $perPage,
]);
return view('users.index', compact('users', 'search'));
}
}
Route​
$app->get('/users', 'UserController::index');
Il manque quelque chose ?
Si vous rencontrez des problèmes avec la documentation ou si vous avez des suggestions pour améliorer la documentation ou le projet en g énéral, veuillez déposer une issue pour nous, ou envoyer un tweet mentionnant le compte Twitter @bowframework ou sur directement sur le github.