[PHP] Porcjowanie danych (paginacja)

Z tego wpisu dowiesz się jak stworzyć prostą paginację, czyli podzielenie rekordów z bazy na strony.

Na potrzeby tego wpisu załóżmy, że chcemy wyświetlić wpisy bloga. W skrypcie będzie można ustalić liczbę wpisów do wyświetlenia na pojedynczej stronie. Do komunikacji z bazą danych użyjemy PDO.

Zatem do dzieła. Na początku musimy połączyć się z bazą danych:

$host = 'localhost';
$db_name = 'baza danych';
$db_user = 'użytkownik';
$db_pass = 'hasło';

try {

    $pdo = new PDO("mysql:host=$host;dbname=$db_name;charset=utf8", $db_user, $db_pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
}

catch(PDOException $e) {

    echo 'Połączenie nie powiodło się: ' . $e->getMessage();
    
}

Następnie ustalmy liczbę wpisów na stronie np. 10:

$per_page = 10;

Trzeba też ustawić aktualną stronę:

$current_page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$current_page = max($current_page, 1);

Musimy również obliczyć offset:

$offset = ($current_page - 1) * $per_page;

Teraz można wykonać zapytanie z ustalonymi wcześniej limitem wpisów i ofsetem:

$stm = $pdo->prepare("SELECT * FROM posts LIMIT :limit OFFSET :offset");
$stm->bindValue(':limit', $per_page, PDO::PARAM_INT);
$stm->bindValue(':offset', $offset, PDO::PARAM_INT);
$stm->execute();
$posts = $stm->fetchAll(PDO::FETCH_ASSOC);
unset($stm);

Następnie musimy pobrać liczbę rekordów:

$stm = $pdo->query("SELECT COUNT(*) FROM posts");
$total_posts = $stm->fetchColumn();
$total_pages = ceil($total_posts / $per_page);

Możemy już wyświetlać wpisy:

if($total_posts > 0) {

    foreach($posts as $post) {
    
        echo '<h2>' . htmlspecialchars($post['title']) . '</h2>';
        echo '<p>' . htmlspecialchars($post['content']) . '</p>';
        
    }
    
}

else {

    echo '<p>Nie znaleziono wpisów.</p>';
    
}

Pod wpisami generujemy linki paginacji:

echo '<div class="pagination">';

// Link do pierwszej strony
if($current_page > 1) {
    echo '<a href="?page=1">Pierwsza strona</a> ';
}

// Link do poprzedniej strony
if ($current_page > 1) {
    echo '<a href="?page=' . ($current_page - 1) . '">Poprzednia</a> ';
}

// Paginacja numerów stron
for($i = 1; $i <= $total_pages; $i++) {

    if($i == $current_page) {
    
        echo '<strong>' . $i . '</strong> '; // Bieżąca strona
        
    }
    
    else {
    
        echo '<a href="?page=' . $i . '">' . $i . '</a> ';
        
    }
    
}

// Link do następnej strony
if($current_page < $total_pages) {

    echo '<a href="?page=' . ($current_page + 1) . '">Następna</a> ';
    
}

// Link do ostatniej strony
if($current_page < $total_pages) {

    echo '<a href="?page=' . $total_pages . '">Ostatnia strona</a>';
    
}

echo '</div>';

Gotowe! Oto cały kod:

<?php

// Połączenie z bazą danych
$host = 'localhost';
$db_name = ' baza danych';
$db_user = 'użytkownik';
$db_pass = 'hasło';

try {

    $pdo = new PDO("mysql:host=$host;dbname=$db_name;charset=utf8", $db_user, $db_pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
}

catch(PDOException $e) {

    echo 'Połączenie nie powiodło się: ' . $e->getMessage();
    
}

// Ustalanie liczby artykułów na stronie
$per_page = 10;

// Ustalanie aktualnej strony
$current_page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT) ?: 1;
$current_page = max($current_page, 1); // Upewnij się, że strona jest większa lub równa 1

// Obliczanie offsetu
$offset = ($current_page - 1) * $per_page;

// Zapytanie do bazy danych
$stm = $pdo->prepare("SELECT * FROM articles LIMIT :limit OFFSET :offset");
$stm->bindValue(':limit', $per_page, PDO::PARAM_INT);
$stm->bindValue(':offset', $offset, PDO::PARAM_INT);
$stm->execute();
$articles = $stm->fetchAll(PDO::FETCH_ASSOC);
unset($stm);

// Pobieramy liczbę wpisów
$stm = $pdo->query("SELECT COUNT(*) FROM posts");
$total_posts = $stm->fetchColumn();
$total_pages = ceil($total_posts / $per_page);

// Wyświetlanie wpisów
if($total_articles > 0) {

    foreach ($articles as $article) {
    
        echo '<h2>' . htmlspecialchars($article['title']) . '</h2>';
        echo '<p>' . htmlspecialchars($article['content']) . '</p>';
        
    }
    
}

else {

    echo '<p>Nie znaleziono wpisów.</p>';
    
}

// Generowanie linków paginacji
echo '<div class="pagination">';

// Link do pierwszej strony
if($current_page > 1) {

    echo '<a href="?page=1">Pierwsza strona</a> ';
    
}

// Link do poprzedniej strony
if($current_page > 1) {

    echo '<a href="?page=' . ($current_page - 1) . '">Poprzednia</a> ';
    
}

// Numery stron
for($i = 1; $i <= $total_pages; $i++) {

    if($i == $current_page) {
    
        echo '<strong>' . $i . '</strong> '; // Bieżąca strona
        
    }
    
    else {
    
        echo '<a href="?page=' . $i . '">' . $i . '</a> ';
        
    }
    
}

// Link do następnej strony
if($current_page < $total_pages) {

    echo '<a href="?page=' . ($current_page + 1) . '">Następna</a> ';
    
}

// Link do ostatniej strony
if($current_page < $total_pages) {

    echo '<a href="?page=' . $total_pages . '">Ostatnia strona</a>';
    
}

echo '</div>';

Komentarze

Popular

[C++] Jak obliczyć pole i obwód trapezu?

[HTML] Jak wyśrodkować tekst?

[PHP] Jak pobrać adres strony?