Pagination utilisant la limite MySQL, OFFSET

j'ai un code qui limite les données à seulement 4 éléments par page. La colonne que j'utilise a environ 20-30 articles, donc je dois faire ceux répartis à travers les pages.

sur la première page, j'ai:

    $result = mysqli_query($con,"SELECT * FROM menuitem LIMIT 4");
{
  echo "<tr>";
  echo "<td align='center'><img src="" . $row['picturepath'] . "" /></td>";
  echo "<td align='center'>" . $row['name'] . "</td> <td align='center'> <input type='button' value='More Info'; onclick="window.location='more_info.php?';"> </td>";
  echo "<td align='center'>" . $row['price'] . "</td> <td align='center'> <input type='button' value='Add to Order' onclick=''> </td>";
  echo "</tr>";
 }
echo "</table>";

mysqli_close($con);

    ?> 

    <table width="1024" align="center" >
        <tr height="50"></tr>
            <tr>
                <td width="80%" align="right">
                    <a href="itempage2.php">NEXT</a>
                </td>
                <td width="20%" align="right">
                    <a href="">MAIN MENU</a>
                </td>
            </tr>
    </table>

Vous remarquerez vers le bas de la page ma balise d'ancrage dans les listes de la deuxième page, "itempage2.php". À la page 2 de l'article, j'ai le même code, sauf que mon instruction select affiche le décalage de 4.

$result = mysqli_query($con,"SELECT * FROM menuitem LIMIT 4 offset 4");

cela fonctionne, de cette façon quand il y a un nombre prédéterminé d'articles dans ma base de données. Mais il n'est pas bon. Je dois créer une nouvelle page seulement s'il y a plus d'articles, pas codé dur dans lui comme il est maintenant.

Comment puis-je créer plusieurs pages sans avoir à coder chaque nouvelle page, et offset?

22
demandé sur Mike Brant 2013-12-04 04:12:25

3 réponses

tout d'abord, ne pas avoir un script de serveur séparé pour chaque page, c'est juste de la folie. La plupart des applications implémentent la pagination via l'utilisation d'un paramètre de pagination dans L'URL. Quelque chose comme:

http://yoursite.com/itempage.php?page=2

vous pouvez accéder au numéro de page demandé via $_GET['page'] .

cela rend votre formulation SQL vraiment facile:

// determine page number from $_GET
$page = 1;
if(!empty($_GET['page'])) {
    $page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
    if(false === $page) {
        $page = 1;
    }
}

// set the number of items to display per page
$items_per_page = 4;

// build query
$offset = ($page - 1) * $items_per_page;
$sql = "SELECT * FROM menuitem LIMIT " . $offset . "," . $items_per_page;

donc par exemple si input ici était page=2 , avec 4 lignes par page, votre requête serait "

SELECT * FROM menuitem LIMIT 4,4

C'est donc le problème de base de la pagination. Maintenant, vous avez l'exigence supplémentaire que vous voulez comprendre le nombre total de pages (de sorte que vous pouvez déterminer si "page suivante" devrait être affichée ou si vous vouliez permettre l'accès direct à la page X via un lien).

pour ce faire, vous devez comprendre le nombre de lignes dans la table.

vous pouvez simplement faire cela avec un appel DB avant d'essayer de revenir votre enregistrement limité réel (je dis avant puisque vous voulez évidemment valider que la page demandée existe).

c'est en fait assez simple:

$sql = "SELECT your_primary_key_field FROM menuitem";
$result = mysqli_query($con, $sql);
if(false === $result) {
   throw new Exception('Query failed with: ' . mysqli_error());
} else {
   $row_count = mysqli_num_rows($result);
   // free the result set as you don't need it anymore
   mysqli_free_result($result);
}

$page_count = 0;
if (0 === $row_count) {  
    // maybe show some error since there is nothing in your table
} else {
   // determine page_count
   $page_count = (int)ceil($row_count / $items_per_page);
   // double check that request page is in range
   if($page > $page_count) {
        // error to user, maybe set page to 1
        $page = 1;
   }
}

// make your LIMIT query here as shown above


// later when outputting page, you can simply work with $page and $page_count to output links
// for example
for ($i = 1; $i <= $page_count; $i++) {
   if ($i === $page) { // this is current page
       echo 'Page ' . $i . '<br>';
   } else { // show link to other page   
       echo '<a href="/menuitem.php?page=' . $i . '">Page ' . $i . '</a><br>';
   }
}
71
répondu Mike Brant 2016-02-09 15:26:19

Utiliser .. LIMIT :pageSize OFFSET :pageStart

:pageStart est lié à_page_index (i.e. 0 pour la première page) * number_of_items_per_pages (e.g. 4) et :pageSize est lié à number_of_items_per_pages.

pour détecter" a plus de pages", utilisez SQL_CALC_FOUND_ROWS ou utilisez .. LIMIT :pageSize OFFSET :pageStart + 1 et détectez un enregistrement de dernière page manquant (pageSize+1). Inutile de dire que, pour les pages avec un index > 0, il existe une page précédente.

si la valeur de l'index de la page est intégrée dans L'URL (par exemple dans les liens" Page précédente "et" page suivante"), elle peut être obtenue via l'élément approprié $_GET .

3
répondu user2864740 2017-05-23 11:54:12

si vous voulez que ce soit simple, allez-y et essayez-le.

$page_number = mysqli_escape_string($con, $_GET['page']);
$count_per_page = 20;
$next_offset = $page_number * $count_per_page;
$cat =mysqli_query($con, "SELECT * FROM categories LIMIT $count_per_page OFFSET $next_offset");
while ($row = mysqli_fetch_array($cat))
        $count = $row[0];

le reste dépend de vous. Si vous avez des résultats venant de deux tableaux, je vous suggère d'essayer une approche différente.

2
répondu Peter Gruppelaar 2014-10-16 21:32:54