Programing

게시판 페이징 처리 (PHP예제)

2025. 5. 18. 10:29
반응형

웹 애플리케이션에서 게시판, 상품 목록, 검색 결과 등 많은 데이터를 다룰 때는 한 페이지에 모든 항목을 출력하는 것보다, 일정 개수씩 나눠서 보여주는 페이징 처리가 필요합니다. 이 글에서는 PHP로 구현한 페이징 처리 예제를 기반으로, 각 부분의 동작 원리와 구현 포인트를 설명합니다.

 


전체 코드 샘플

<?php

# Getting Parameter And Default Variable Setting ###############################
$page_now = $_GET['page_now'];
$page_row = $_GET['page_row'];
$total_search = $_GET['total_search'];

# Parameter to Query Processing ################################################
if ($total_search)
{
    $tmp_search = explode(" ", $total_search);

    foreach ($tmp_search as $k=>$v)
    {
        $ARR_SRCH_SQL[] = "board_subject like '%{$v}%'";
        $ARR_SRCH_SQL[] = "strip_tags(board_content) like '%{$v}%'";
    }
    $ARR_SRCH_SQL = implode(" or ", $ARR_SRCH_SQL);
    $SRCH_SQL .= " AND ({$ARR_SRCH_SQL})";
}

# List SQL Query ###############################################################
$page_num   = 10;
$page_row   = $page_row != null ? $page_row : 20;
$page_now   = $page_now != null ? $page_now : 0;
$offset     = $page_now * $page_row;

$total_row = (int) $db->get_var("SELECT COUNT(*) FROM board WHERE 1 = 1 {$SRCH_SQL}");
$total_page = (int) ceil($total_row / $page_row);

$list_sql = "SELECT * FROM board WHERE 1 = 1 {$SRCH_SQL} ORDER BY board_pk DESC LIMIT {$offset}, {$page_row}";

$res_sql = $db->get_results($list_sql);

# Create HTML ##################################################################
if ($res_sql)
{
    foreach ($res_sql as $data)
    {
        $HTML .= "
        <tr>
            <td>{$data->board_pk}</td>
            <td>{$data->board_subject}</td>
            <td>{$data->board_write_date}</td>
        </tr>
        ";
    }
}
?>

<form name='frm' action='<?=$_SERVER['PHP_SELF']?>' method='get' class='frm' id='frm'>
<input type='hidden' name='page_now' value='<?=$page_now?>' />

<input type="text" name='total_search' value='<?=$total_search?>'>
<button type='submit'>검색</button>

<?=$HTML?>

<div class="paginate">
<?php
$paginate_html = '';

if ($total_row > 0) {
    // Prev 버튼
    $paginate_html .= "<a href=\"javascript:goList('0')\">Prev End</a>";
    if ($page_now > 0) {
        $paginate_html .= "<a href=\"javascript:goList(" . ($page_now - 1) . ")\"> Prev </a>";
    }

    // 페이지 블록 계산
    $half_block = (int) floor($page_num / 2);
    if ($total_page <= $page_num) {
        $start = 0;
        $end = $total_page;
    } elseif ($page_now <= $half_block) {
        $start = 0;
        $end = $page_num;
    } elseif ($page_now >= $total_page - $half_block) {
        $start = $total_page - $page_num;
        $end = $total_page;
    } else {
        $start = $page_now - $half_block;
        $end = $page_now + $half_block;
    }

    // 페이지 번호 출력
    for ($i = $start; $i < $end; $i++) {
        $display = $i + 1;
        if ($i == $page_now) {
            $paginate_html .= "<strong>{$display}</strong>";
        } else {
            $paginate_html .= "<a href=\"javascript:goList({$i})\">{$display}</a>";
        }
    }

    // Next 버튼
    $last_page = $total_page - 1;
    if ($page_now < $last_page) {
        $paginate_html .= "<a href=\"javascript:goList(" . ($page_now + 1) . ")\"> Next </a>";
    }
    $paginate_html .= "<a href=\"javascript:goList('{$last_page}')\">Next End</a> ";
} else {
    $paginate_html .= "<a href=\"javascript:goList(0)\"> Prev End</a>";
    $paginate_html .= "<a href=\"javascript:goList(0)\"> Prev </a>";
    $paginate_html .= "<strong>1</strong>";
    $paginate_html .= "<a href=\"javascript:goList(0)\"> Next </a>";
    $paginate_html .= "<a href=\"javascript:goList(0)\"> Next End</a>";
}

echo $paginate_html;
?>
</div>
<script type="text/javascript">
function goList(page)
{
    var f=document.frm;
    f.page_now.value=page;
    f.submit();
}
</script>

<style>
.paginate {
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 20px 0;
}
.paginate a,
.paginate strong{border: 1px solid #ccc; padding: 5px 10px; margin: 0 5px; text-decoration: none; color: #333;}
.paginate strong{
    background-color: #007bff;
    color: #fff;
}
</style>
</form>

1. 파라미터 수집 및 초기값 설정

$page_now = $_GET['page_now'];
$page_row = $_GET['page_row'];
$total_search = $_GET['total_search'];
  • page_now: 현재 페이지 번호
  • page_row: 한 페이지에 출력할 게시글 수 (기본값 20)
  • total_search: 검색 키워드

2. 검색 조건 처리

if ($total_search)
{
    $tmp_search = explode(" ", $total_search);

    foreach ($tmp_search as $v)
    {
        $ARR_SRCH_SQL[] = "board_subject like '%{$v}%'";
        $ARR_SRCH_SQL[] = "strip_tags(board_content) like '%{$v}%'";
    }
    $ARR_SRCH_SQL = implode(" or ", $ARR_SRCH_SQL);
    $SRCH_SQL .= " AND ({$ARR_SRCH_SQL})";
}
  • 검색어가 존재할 경우, 제목과 내용에서 해당 키워드를 포함하는 조건을 SQL에 추가합니다.
  • 다중 키워드 지원을 위해 공백 기준으로 분할하고 LIKE 검색을 반복 적용합니다.

3. 페이징 변수 계산

$page_num = 10;
$page_row = $page_row != null ? $page_row : 20;
$page_now = $page_now != null ? $page_now : 0;
$offset = $page_now * $page_row;
  • $offset: LIMIT 절에 사용될 시작 위치 계산
  • $page_num: 한 번에 보여줄 페이지 수 (예: 1~10)

4. 전체 게시물 수 조회 및 페이지 계산

$total_row = (int) $db->get_var("SELECT COUNT(*) FROM board WHERE 1 = 1 {$SRCH_SQL}");
$total_page = (int) ceil($total_row / $page_row);
  • 전체 행 수를 구한 뒤, 페이지 수를 계산합니다.

5. 데이터 조회 및 리스트 생성

$list_sql = "SELECT * FROM board WHERE 1 = 1 {$SRCH_SQL} ORDER BY board_pk DESC LIMIT {$offset}, {$page_row}";
$res_sql = $db->get_results($list_sql);
  • 지정된 조건과 오프셋, 제한 수에 따라 게시글을 조회합니다.

6. 페이징 HTML 출력

// Prev / Next 버튼, 페이지 번호 계산
$half_block = floor($page_num / 2);
  • 현재 페이지 위치에 따라 시작 번호와 끝 번호를 조절하여 페이징 블록을 유동적으로 구성합니다.
  • Prev, Next, 처음/끝으로 이동하는 버튼을 포함합니다.

7. HTML 출력 및 폼

<form name='frm' action='<?=$_SERVER['PHP_SELF']?>' method='get'>
    <input type='hidden' name='page_now' value='<?=$page_now?>'>
    <input type='text' name='total_search' value='<?=$total_search?>'>
    <button type='submit'>검색</button>
</form>
  • 검색 폼과 페이징 파라미터를 유지하기 위한 hidden input 활용
  • 페이지 이동은 JavaScript 함수 goList()를 통해 처리됨
function goList(page) {
    var f = document.frm;
    f.page_now.value = page;
    f.submit();
}

8. 스타일링

.paginate {
    display: flex;
    justify-content: center;
    margin: 20px 0;
}
.paginate a,
.paginate strong {
    border: 1px solid #ccc;
    padding: 5px 10px;
    margin: 0 5px;
    text-decoration: none;
    color: #333;
}
.paginate strong {
    background-color: #007bff;
    color: #fff;
}
  • 현재 페이지 강조와 기본 스타일 적용을 통해 UX 향상

마무리

이 예제는 페이징 처리의 기본을 반영한 코드입니다.

  • 검색 조건 처리
  • 동적 페이지 블록 계산
  • JavaScript 연동

을 통해 유저 친화적인 인터페이스를 만들 수 있습니다.

실제 프로젝트에서는 SQL 인젝션 방지, XSS 필터링, 페이지 범위 제한 등을 추가로 고려해야 합니다.

반응형

'Programing' 카테고리의 다른 글

엑셀/스프레디시트에서 숫자를 한글로 표기하는 방법 총정리 (Excel to Hangul Conversion)  (4) 2025.06.11
개발 중 자주 만나는 CORS 오류와 해결법 정리 (CORS Error in Web Development)  (0) 2025.06.10
리팩토링의 원칙과 사례 (Refactoring)  (0) 2025.06.02
웹 성능 측정 지표 (LCP, FID 등)과 JS 최적화 방법  (0) 2025.04.29
브라우저 렌더링 최적화를 위한 비동기 패턴 정리  (1) 2025.04.29
Form 입력 유효성 검사 및 실시간 피드백 구현 가이드  (0) 2025.04.29
퍼센트 계산, 백분율 계산 방식  (0) 2015.06.11
PHP, MySQL 및 Google 지도를 사용하여 매장 검색기 만들기  (0) 2012.06.13
'Programing' 카테고리의 다른 글
  • 개발 중 자주 만나는 CORS 오류와 해결법 정리 (CORS Error in Web Development)
  • 리팩토링의 원칙과 사례 (Refactoring)
  • 웹 성능 측정 지표 (LCP, FID 등)과 JS 최적화 방법
  • 브라우저 렌더링 최적화를 위한 비동기 패턴 정리
Dongkkase
Dongkkase
개발자로 일하면서 부딪히는 문제풀이가 누군가에게 도움이 되길 바라며
    반응형
  • Dongkkase
    정집사의 개발로그
    Dongkkase
  • 전체
    오늘
    어제
    • All (478)
      • 금융 (61)
      • Programing (295)
        • Algorithm (39)
        • API (2)
        • javascript (122)
        • CSS (8)
        • HTML (10)
        • PHP (15)
        • JAVA (27)
        • JSP (17)
        • JSP 예제 (1)
        • IOS (1)
        • Android (1)
        • Sencha Touche (1)
        • bat file, cmd (0)
        • 디버깅 (2)
        • SQL (21)
        • MS-SQL (1)
        • MySQL (13)
        • 보안 (5)
      • Server (14)
        • Docker (1)
        • Windows (9)
        • Linux (3)
        • jeus (1)
      • Database (6)
      • IT 일반 (15)
      • 리뷰 (38)
        • Book (17)
        • 제품 (2)
        • 영화 소개 (11)
        • 음악 소개 (7)
      • 잡생각 (36)
        • 회고 (3)
        • 컬럼 (4)
        • 자료실 (6)
        • 낙서장 (12)
        • 위시리스트 (2)
        • WOW (1)
        • 덕 (1)
  • 인기 글

  • 최근 댓글

  • 태그

    JavaScript
    디자인패턴
    자바스크립트유틸
    IT 관련
    IT·컴퓨터
    js패턴
    IT블로그
    jsp
    SQL
    php
    자바스크립트
    기초
    iT's MY LiFE
    블로그
    It
    Java
    읽고 싶은 책
    위시리스트
    사고 싶은 책
    자바
Dongkkase
게시판 페이징 처리 (PHP예제)
상단으로

티스토리툴바