Gestire la paginazione dei dati con <strong>array_chunk</strong> in PHP

by theArchitect
SHARE
Gestire la paginazione dei dati con <strong>array_chunk</strong> in PHP
© Guida-HTML5.it

Introduzione

Quando un’applicazione deve mostrare molti dati, visualizzarli tutti in una sola pagina può creare problemi di usabilità e prestazioni. Un elenco di migliaia di prodotti, ordini o messaggi rende la pagina difficile da consultare e può aumentare il tempo necessario per generare la risposta.

Una tecnica comune è la paginazione: i dati vengono divisi in piccoli blocchi e l’utente visualizza una pagina alla volta. In PHP, la funzione array_chunk permette di suddividere un array in più array di dimensione stabilita.

La sintassi principale è:

<?php

$blocchi = array_chunk($array, $dimensione);

?>

Il primo parametro è l’array da dividere, mentre il secondo indica quanti elementi inserire in ogni blocco. Per impostazione predefinita, le chiavi originali vengono reindicizzate partendo da zero. Se necessario, è possibile conservare le chiavi originali passando true come terzo parametro.

Codice completo

<?php

// Elenco di prodotti che potrebbe provenire da un database
$prodotti = [
    [
        ´nome´ => ´Tastiera meccanica´,
        ´categoria´ => ´Accessori´,
        ´prezzo´ => 79.90
    ],
    [
        ´nome´ => ´Mouse ergonomico´,
        ´categoria´ => ´Accessori´,
        ´prezzo´ => 34.50
    ],
    [
        ´nome´ => ´Monitor 27 pollici´,
        ´categoria´ => ´Display´,
        ´prezzo´ => 249.99
    ],
    [
        ´nome´ => ´Webcam Full HD´,
        ´categoria´ => ´Video´,
        ´prezzo´ => 59.00
    ],
    [
        ´nome´ => ´Microfono USB´,
        ´categoria´ => ´Audio´,
        ´prezzo´ => 89.90
    ],
    [
        ´nome´ => ´Cuffie wireless´,
        ´categoria´ => ´Audio´,
        ´prezzo´ => 119.00
    ],
    [
        ´nome´ => ´Hub USB-C´,
        ´categoria´ => ´Accessori´,
        ´prezzo´ => 42.75
    ]
];

// Numero di elementi da mostrare per pagina
$elementiPerPagina = 3;

// Numero di pagina richiesto dall´utente
$paginaRichiesta = filter_input(
    INPUT_GET,
    ´pagina´,
    FILTER_VALIDATE_INT
);

// Se il parametro non è valido, si usa la prima pagina
$paginaCorrente = $paginaRichiesta !== false && $paginaRichiesta !== null
    ? $paginaRichiesta
    : 1;

// La pagina deve essere almeno la numero 1
$paginaCorrente = max(1, $paginaCorrente);

// Divide l´elenco in blocchi da tre prodotti
$pagine = array_chunk($prodotti, $elementiPerPagina);

// Calcola il numero totale di pagine
$totalePagine = count($pagine);

// Se la pagina richiesta supera il limite, usa l´ultima disponibile
if ($totalePagine > 0) {
    $paginaCorrente = min($paginaCorrente, $totalePagine);
}

// Recupera il blocco corrispondente alla pagina corrente
$prodottiPagina = $totalePagine > 0
    ? $pagine[$paginaCorrente - 1]
    : [];

echo ´<h1>Catalogo prodotti</h1>´;

if (count($prodottiPagina) === 0) {
    echo ´<p>Nessun prodotto disponibile.</p>´;
} else {
    echo ´<ul>´;

    foreach ($prodottiPagina as $prodotto) {
        $nome = htmlspecialchars(
            $prodotto[´nome´],
            ENT_QUOTES,
            ´UTF-8´
        );

        $categoria = htmlspecialchars(
            $prodotto[´categoria´],
            ENT_QUOTES,
            ´UTF-8´
        );

        $prezzo = number_format(
            $prodotto[´prezzo´],
            2,
            ´,´,
            ´.´
        );

        echo "<li>$nome - $categoria - € $prezzo</li>";
    }

    echo ´</ul>´;
}

// Mostra i collegamenti di navigazione
if ($totalePagine > 1) {
    echo ´<nav aria-label="Paginazione">´;

    if ($paginaCorrente > 1) {
        $paginaPrecedente = $paginaCorrente - 1;
        echo ´<a href="?pagina=´ . $paginaPrecedente . ´">´;
        echo ´Pagina precedente</a> ´;
    }

    echo " Pagina $paginaCorrente di $totalePagine ";

    if ($paginaCorrente < $totalePagine) {
        $paginaSuccessiva = $paginaCorrente + 1;
        echo ´ <a href="?pagina=´ . $paginaSuccessiva . ´">´;
        echo ´Pagina successiva</a>´;
    }

    echo ´</nav>´;
}

?>

Spiegazione

Suddividere l’array

La riga seguente crea un nuovo array chiamato $pagine:

$pagine = array_chunk($prodotti, $elementiPerPagina);

Con sette prodotti e tre elementi per pagina, il risultato sarà composto da tre blocchi:

  • il primo contiene i prodotti da 1 a 3;
  • il secondo contiene i prodotti da 4 a 6;
  • il terzo contiene il prodotto rimanente.

È importante ricordare che l’ultimo blocco può contenere meno elementi rispetto agli altri. Questo comportamento è normale e deve essere gestito senza assumere che ogni pagina abbia sempre la stessa quantità di dati.

Convertire il numero di pagina in un indice

Gli utenti ragionano generalmente in termini di pagine numerate a partire da 1: pagina 1, pagina 2 e così via. Gli array PHP, invece, utilizzano normalmente indici a partire da 0.

Per questo motivo, per recuperare la pagina richiesta viene utilizzata questa espressione:

$prodottiPagina = $pagine[$paginaCorrente - 1];

Se l’utente richiede la pagina 1, PHP accede all’indice 0. Se richiede la pagina 2, accede all’indice 1.

Validare l’input

Il numero di pagina arriva tramite il parametro GET, ad esempio ?pagina=2. Non bisogna utilizzare direttamente questo valore senza controllarlo, perché l’utente potrebbe inviare testo, numeri negativi o valori troppo grandi.

La funzione filter_input verifica che il valore sia un intero. Successivamente, max(1, $paginaCorrente) impedisce di utilizzare numeri inferiori a 1. Infine, min limita il valore all’ultima pagina disponibile.

Conservare le chiavi originali

Per impostazione predefinita, array_chunk reindicizza gli elementi:

<?php

$utenti = [
    10 => ´Mario´,
    25 => ´Lucia´,
    40 => ´Paolo´
];

$blocchi = array_chunk($utenti, 2);

print_r($blocchi);

/*
Le chiavi interne ai blocchi diventano:
Array
(
    [0] => Mario
    [1] => Lucia
)
*/

?>

Se gli indici hanno un significato importante, è possibile conservarli passando true:

<?php

$blocchi = array_chunk($utenti, 2, true);

?>

Best practice

  • Valida sempre i parametri esterni: i valori presenti nell’URL devono essere considerati non attendibili.
  • Imposta una dimensione ragionevole: un numero troppo elevato di elementi per pagina riduce i vantaggi della paginazione.
  • Gestisci l’array vuoto: quando non esistono dati, array_chunk restituisce un array vuoto e non ci sono pagine da mostrare.
  • Proteggi l’output HTML: usa htmlspecialchars quando stampi dati provenienti da utenti o database.
  • Non usare array_chunk per enormi dataset: la funzione divide un array già caricato in memoria. Con milioni di righe è preferibile la paginazione direttamente nel database con LIMIT e OFFSET.
  • Mantieni separata la logica: calcolo delle pagine, recupero dei dati e generazione HTML dovrebbero idealmente appartenere a livelli distinti dell’applicazione.

Riepilogo

array_chunk è una funzione semplice ma molto utile per dividere un array in blocchi omogenei. È particolarmente adatta a piccoli cataloghi, risultati già presenti in memoria, menu e liste amministrative.

Per creare una paginazione affidabile occorre combinare la funzione con la validazione del parametro ricevuto, il controllo dei limiti e una corretta gestione dell’array vuoto. In scenari con grandi quantità di dati, invece, la soluzione più efficiente consiste nel paginare già durante la query al database, evitando di caricare tutto in memoria.

Approfondisci con risorse ufficiali

SHARE