목록 출력 및 페이지 네이션

이태현·2025년 7월 25일

Web 개발

목록 보기
19/53
post-thumbnail

회원관리 - 목록 출력

admin/member.php

  <?php

  $g_title = "해커들의 놀이터";
  $js_array = ["../js/home.js"];
  $menu_code = "member";

  include "inc_common.php";
  include "inc_header.php";
  include "../inc/dbconfig.php";
  include "../inc/member.php"; // 회원관리 Class
  include "../inc/lib.php"; // 페이지네이션

  // $total, $limit, $page_limit, $page, $param

  $mem = new Member($db);

  $total = $mem->total();
  $limit = 5;
  $page_limit = 5;
  $page = (isset($_GET["page"]) && $_GET["page"] != "" && is_numeric($_GET["page"])) ? $_GET["page"] : 1;
  $param = "";

  $memArr = $mem->list($page, $limit);

  ?>
  <main class="w-75 mx-auto border rounded-5 p-5 " style="height: calc(100vh - 265px);">

    <div class="container">
      <h3 class="">회원관리</h3>
    </div>

    <table class="table table-border">
      <tr>
        <th>번호</th>
        <th>아이디</th>
        <th>이름</th>
        <th>이메일</th>
        <th>등록일시</th>
        <th>관리</th>
      </tr>
      <?php
      foreach ($memArr as $row) {
        // 2025-07-23 22-35
        // $row["create_at"] = substr($row["create_at"], 0, 16);
      ?>
        <tr>
          <td><?= $row["idx"]; ?></td>
          <td><?= $row["id"]; ?></td>
          <td><?= $row["name"]; ?></td>
          <td><?= $row["email"]; ?></td>
          <td><?= $row["create_at"]; ?></td>
          <td>
            <button class="btn btn-primary btn-sm">수정</button>
            <button class="btn btn-danger btn-sm">삭제</button>
          </td>
        </tr>
      <?php
      }
      ?>
    </table>

    <?php
    echo my_pagination($total, $limit, $page_limit, $page, $param);

    ?>
  </main>
  <?php
  include "inc_footer.php";
  ?>
  • member 클래스에 list() 함수를 하나 만들어서 회원정보를 가져오게 합니다.
  • mem->list($page, $limit)에서 넘어온 값
  • foreach 반복문을 사용하여 해당 배열 값을 $row 담아서 뿌려줍니다.
  • 중간에 주석 처리 한 코드는 보통 계정 생성을 하면 날짜를 확인하는데 초 단위까지는 굳이 나타낼 필요는 없어서 뒷부분을 없애주기 위해서 php 부분에서 처리를 해본 겁니다. 어차피 밑에 DB 쪽 코드를 보시면 아시겠지만 이미 DB 쪽에서 시간 관련해서 처리를 했기 때문에 기존에 있던 코드를 주석 처리했던 겁니다.
$row["create_at"] = substr($row["create_at"], 0, 16);

회원관리 - DB

inc/member.php

// DB 정보 리스트
  public function list($page, $limit)
  {
    $start = ($page - 1) * $limit;
    $sql = "SELECT idx, id, name, email, DATE_FORMAT(create_at,'%Y-%m-%d %H-%i') AS create_at FROM member ORDER BY idx DESC LIMIT " . $start . "," . $limit;
    $stmt = $this->conn->prepare($sql);
    $stmt->setFetchMode(PDO::FETCH_ASSOC);
    $stmt->execute();

    return $stmt->fetchAll();
  }

Pagination - 페이지네이션

inc/lib.php

<?php
function my_pagination($total, $limit, $page_limit, $page, $param)
{

  $total_page = ceil($total / $limit); // 107 / 5 = 21.4 == 22
  $start_page = ((floor(($page - 1) / $page_limit)) * $page_limit) + 1; // 1
  $end_page = $start_page + $page_limit - 1; // 1 + 5 -1 = 5

  if ($end_page > $total_page) {
    $end_page = $total_page;
  }

  $prev_page = $start_page - 1; // 0

  if ($prev_page < 1) { // 1
    $prev_page = 1;
  }

  $rs_str = '<nav>
  <ul class="pagination">';

  $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . '?page=1' . $param . '">First</a></li>';

  if ($prev_page > 1) {
    $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . '?page=' . $prev_page . $param . '">Prev</a></li>';
  }

  for ($i = $start_page; $i <= $end_page; $i++) {
    if ($i == $page) {
      $rs_str .= "<li class=\"page-item active\"><a class=\"page-link\" href=\"#\">{$i}</a></li>";
    } else {
      $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . "?page={$i}{$param}\">{$i}</a></li>";
    }
  }

  $next_page = $end_page + 1;
  if ($next_page <= $total_page) {
    $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . "?page={$next_page}{$param}\">Next</a></li>";
  }

  if ($page < $total_page) {
    $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . "?page={$total_page}{$param}\">Last</a></li>";
  }

  $rs_str .= '</ul></nav>';

  return $rs_str;
}
  • 코드를 이해하시면 더 좋겠지만 굳이 몰라도 사용하시는데는 문제없을 겁니다.
  • 일정 수준 데이터가 많아지면 위에 보이는 것처럼 pagination(페이지 네이션)을 통해서 페이지 이동을 합니다. 왜냐하면 그게 더 관리하기도 편하고 보이는 부분도 깔끔하고 사용하기 좋기 때문입니다. 따라서 pagination처리는 반드시 게시판이든 회원관리든 데이터가 많아서 더 이상 화면에 담지 못했을 때 꼭 필요한 방식이라고 생각하시면 좋겠습니다.
  • 주석 부분은 제가 계산하면서 하다 보니 결과를 작성할 곳이 마땅치 않아서 표시해둔 겁니다. 지우셔도 무방합니다.

이제 간단히 설명을 해보자면

1. function my_pagination($total, $limit, $page_limit, $page, $param) 함수를 만들어 사용해줄겁니다.

  • total : 전체 페이지 수

  • limit : 해당 페이지에 보일 개수
    ex) 5개로 제한하면 5개의 데이터가 나타납니다.

  • page_limit : 페이지 네이션 개수 제한
    ex) 3개로 제한하면 3개만 나타납니다.

  • page : 현재 페이지의 위치(주소)
    ex) 현재 페이지가 page=6이라면 해당 페이지로 이동

  • param : 지금은 사용하지 않지만 추후에 검색 기능에 사용될 기능입니다.
    ex) 네이버 검색 시 해당 키워드로 검색

2. 총 페이지 수, 시작페이지, 마지막 페이지, 이전 페이지

$total_page = ceil($total / $limit); // 107 / 5 = 21.4 == 22
  $start_page = ((floor(($page - 1) / $page_limit)) * $page_limit) + 1; // 1
  $end_page = $start_page + $page_limit - 1; // 1 + 5 -1 = 5

  if ($end_page > $total_page) {
    $end_page = $total_page;
  }

  $prev_page = $start_page - 1; // 0
  • total_page에 ceil(total / limit)를 사용하여 총 페이지 수를 구합니다. ceil 함수는 올림 한 수입니다.
    필자는 총 107개의 데이터를 가지고 있으므로 107 / 5 = 21.4 == 22 계산 값이 나왔습니다.

  • start_page에 ((floor((page - 1) / page_limit)) * page_limit) + 1을 하여 시작페이지를 구했습니다.
    floor()는 내림함 수입니다. 시작페이지는 현재 페이지에서 -1을 해주고 그 값과 페이지 제한 값으로 나누어줍니다. 이렇게 해야 처음 페이지에서 1,2,3,4,5 페이지까지는 값이 1이기 때문에 이 값을 가지고 1,2,3 페이지를 구분해 줄 수 있습니다.

  • end_page에 시작페이지와 페이지 제한 값을 더하고 -1을 해줍니다. 예를 들어보겠습니다.
    ex) 1번째 화면에서는 1~5까지 페이지 네이션을 보여줘야 하고 그 이후 2번째 화면에서는 6~10까지 있는 페이지 네이션을 보여줘야 합니다. 따라서 1번째 화면에서는 최댓값이 5가 마지막이므로 2번째 화면으로 이동하면 시작페이지 값이 6으로 바뀌어서 마지막 페이지에 대입해 보면 2번째 화면에서는 처음은 6이고 마지막 페이지는 10인 걸 알 수 있습니다.

    • 2번째 화면으로 이동했을 때
      시작페이지 = ((floor((6 - 1) / 5)) * 5) + 1 = 6이므로,
      마지막 페이지 = 6 + 5 - 1 = 10 페이지 네이션

3. 마지막 페이지가 총 페이지 수 보다 클 경우

if ($end_page > $total_page) {
    $end_page = $total_page;
  }


해당 조건문을 주지 않는다면

  • 위와 같이 데이터가 없어도 페이지가 추가되어 불필요한 기능들이 생깁니다.

4. 페이지에 데이터 뿌려주기

  $rs_str = '<nav>
  <ul class="pagination">';

  $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . '?page=1' . $param . '">First</a></li>';

  if ($prev_page > 1) {
    $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . '?page=' . $prev_page . $param . '">Prev</a></li>';
  }

  for ($i = $start_page; $i <= $end_page; $i++) {
    if ($i == $page) {
      $rs_str .= "<li class=\"page-item active\"><a class=\"page-link\" href=\"#\">{$i}</a></li>";
    } else {
      $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . "?page={$i}{$param}\">{$i}</a></li>";
    }
  }

  $next_page = $end_page + 1;
  if ($next_page <= $total_page) {
    $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . "?page={$next_page}{$param}\">Next</a></li>";
  }

  if ($page < $total_page) {
    $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . "?page={$total_page}{$param}\">Last</a></li>";
  }

  $rs_str .= '</ul></nav>';

  return $rs_str;
  • HTML이랑 PHP과 섞여있어서 보기 어려울 수 있지만 하나씩 보다 보면 그리 어렵지는 않을 겁니다. HTML에 있는 기본 문법들에 PHP에서 선언해 주었던 변수들이기 때문에 그동안 구해온 값들을 이제 자리에 맞게 뿌려주기만 하면 되는 부분이라 굳이 설명이 필요하지 않을 거 같습니다.

그래도 아쉬우니 설명해 드리겠습니다.

1. First Page

$rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . '?page=1' . $param . '">First</a></li>';
  • 맨 처음 앞에 있는 페이지로 어느 페이지 있든 첫 번째로 돌아옵니다.
    $_SERVER['PHP_SELF']는 자기 자신 페이지를 나타냅니다.

2. Prev Page

if ($prev_page > 1) {
    $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . '?page=' . $prev_page . $param . '">Prev</a></li>';
  }
  • 6번째 페이지부터 보입니다.

3. Page Button

for ($i = $start_page; $i <= $end_page; $i++) {
    if ($i == $page) {
      $rs_str .= "<li class=\"page-item active\"><a class=\"page-link\" href=\"#\">{$i}</a></li>";
    } else {
      $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . "?page={$i}{$param}\">{$i}</a></li>";
    }
  }
  • foreach 반복문으로 차례대로 반복해 주면 위와 같이 나옵니다.

4. Next Page

$next_page = $end_page + 1;
  if ($next_page <= $total_page) {
    $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . "?page={$next_page}{$param}\">Next</a></li>";
  }
  • Prev 페이지와 마찬가지로 다음 페이지로 이동합니다.

Last Page

if ($page < $total_page) {
    $rs_str .= '<li class="page-item"><a class="page-link" href="' . $_SERVER['PHP_SELF'] . "?page={$total_page}{$param}\">Last</a></li>";
  }
  • First 페이지와 마찬가지로 어디에 있든 마지막 페이지로 이동합니다.

마무리

다음 시간에는 회원관리 검색 기능을 해보겠습니다.

긴 글 봐주셔서 감사합니다.

profile
이해하고 분석하고 지배한다

0개의 댓글