서론
오늘은 게시글에 페이지 기능을 구현하려고 한다.
진짜 페이지 기능 구현하면서 머리가 터지는 줄 알았다..
특히 변수 설정과 블럭 부분...
그럼 시작해보자
먼저 생각할 것은
- 게시글 목록을 페이지 단위로 보여준다.
- 1페이지에 글 5개, 2페이지에 글 5개 - 페이지 개수도 너무 많으면 페이지도 나눠서 보여준다.
- ‘<’ ‘>’ 버튼으로 이전/다음 블럭으로 이동 - 페이지 번호 묶음을 블럭(Block) 단위로 관리한다.
- '1페이지,2페이지 등 5페이지'까지 한블럭 - 맨 처음과 마지막으로 이동할 수 있는 버튼을 추가해준다.
- '<<' = 1페이지 '>>' = 마지막 페이지
최종화면
1. 현재페이지에 변수 할당
if(isset($_GET['page'])){
$page = $_GET['page'];
}else{
$page = 1;
}
- 페이지를 이동할 떄는 GET메서드를 사용한다
-페이지 이동은 단순 데이터 조회이기 때문 - GET으로 넘어온 page 파라미터값을 $page에 변수 할당
- 파라미터값이 없을 시 기본인 1페이지 즉, 1 할당
2. 필요한 변수 할당
✅ 매우 헷갈릴 수 있으니 주의
$sql="SELECT * FROM board";
$result = $mysqli->query($sql);
$total_post = $result->num_rows;//총 게시글 수
- board 테이블 컬럼 모두 가져오기
- $total_post(총 게시글 수) DB결과에서 모든 개수를 할당한다.
- 이용자가 적은 모든 게시글
$per_post = 5;//페이지당 보여줄 게시글 수
- $per_post(페이지당 보여줄 게시글 수)
- 1페이지당 보여줄 게시글 개수이다. 나는 5개로 설정했다.
$start = ($page-1)*$per_post;//페이지당 보여줄 게시글 시작번호
- $start(페이지당 보여줄 게시글 시작번호)
- 1페이지에 1,2,3,4,5 라면 $start=1
- 2페이지에 6,7,8,9,10 라면 $start=6
$total_page = ceil($total_post/$per_post);//총 페이지 수
- $total_page(총 페이지 수) = 총 게시글 수/ 페이지 당 보여줄 게시글 수
-총 50개의 게시글이 있다면 1페이지당 5개의 게시글이 보이기 때문에 총 10페이지가 될 것이다.
-만약 48개의 게시글이 있다면 1페이지당 5개지만 9페이지하고 게시글 3개가 남는다
버릴 수 없기 때문에 10페이지가 생성되어야하고 10페이지에는 3개의 게시글만 존재할 것이다.
즉 ,나머지가 없이 올림을 해줘야한다 ( ceil= 올림함수)
per_block = 5;//한 블럭당 보여줄 페이지 수
- $per_block(한 블럭당 보여줄 페이지 수)
-내가 헷갈렸던 블럭이기 때문에 사진으로 같이보자
➡️ 페이지들이 나와있다. 내가 아까 5로 설정했기 때문에 5페이지가 존재한다. 이 묶음이 한 블럭이다.
$total_block = ceil($total_page/$per_block);//총 블럭 수
- $total_block(총 블럭 수) = 총 페이지 수 / 블럭 당 보여줄 페이지 수
- 20개의 페이지가 있다. 블럭 당 나는 5개로 설정했고 그렇다면 4개의 블럭이 필요하다
-1블럭{1,2,3,4,5}, 2블럭{6,7,8,9,10}, 3블럭{11,12,13,14,15}, 4블럭{16,17,18,19,20}
-18개의 페이지가 있다. 그렇다면 세블럭이면 3개의 페이지가 남는다. 즉 4개의 블럭이 필요하기 떄문에 올림해준다.
(이제 이해했다고 생각하고 올림설명은 여기까지)
$current_block = ceil($page/$per_block);//현재 페이지가 속한 블럭
- $current_block(현재 페이지가 속한 블럭) = 현재 페이지 / 한 블럭 당 보여줄 페이지 수
- 블럭당 나는 5개로 설정했다.
-현재 페이지가 속한 블럭은 현재 페이지가 1~5라면 1블럭 6~10이라면 2블럭이다.
-현재페이지가 1~5라고 가정해보자. 내가 설정한 블럭 당 페이지개수(5) 로 나누면
0.2~1이 될 것이다. 즉, 올림을해줘서 1을 맞춰주면 1블럭에 있다는 로직이 된다.
$start_block = ($current_block-1)*$per_block+1;//지금 블럭의 시작 페이지 번호
- $start_block(지금 블럭의 시작 페이지 번호) 복잡하기 떄문에 바로 설명
- 블럭의 시작 페이지 번호란 1블럭은 1페이지, 2블럭은 6페이지, 3블럭은 11페이지이다.
예를 들면,
- 1블럭에 있다고 해보자(1~5페이지) (1블럭- 1)*내가 설정한 블럭 당 페이지 수(5) +1 = 1
- 2블럭에 있다고 해보자(6~10페이지) (2블럭-1)*5 +1 = 6
즉, 블럭의 시작 페이지 번호이다.
$end_block = min(($start_block + $per_block -1),$total_page);//지금 블럭의 마지막 페이지 번호
- $end_block(지금 블럭의 마지막 페이지 번호) 이것도 복잡하니 바로 설명
- min함수란 두 인자를 비교해 더 적은 숫자를 반환한다. (ex. min(5,10) = 5)
- 블럭의 마지막 페이지 번호란 1블럭은 5, 2블럭은 10, 3블럭은 15페이지이다.
min(블럭의 시작 페이지 번호 + 내가 설정한 블럭 당 페이지 수(5) - 1 , 총 페이지수)
예를 들면,
- 1블럭(1~5)이 있고 총 페이지수가 23개라고 해보자
→min(1+5-1, 23) = 5
-2블럭(6~10)이 있고 총 페이지수가 8개라고 해보자
→min(6+5-1,8) = 8
-2블럭에는 페이지수가 6~10페이지가 있어야되는데 8페이지밖에 없다.
그렇기 때문에 이런 것을 걸러내고 마지막 번호만 찾기 위해서 min함수로 더 적은 값을 찾는 것이다.
3. 게시글 가져오기
<?php
$sql_page = "SELECT * FROM board ORDER BY idx DESC LIMIT $start,$per_post";
$res_page = $mysqli->query($sql_page);
while($row = $res_page->fetch_assoc()){
?>
<tr>
<td><?= $row['idx']; ?></td>
<td><?= $row['title']; ?></td>
<td><?= $row['author']; ?></td>
<td><?= $row['post_date']; ?></td>
<td><?= $row['views']; ?></td>
<td><?= $row['likes']; ?></td>
</tr>
<?php } ?>
- ORDER By idx DESC
- idx 기준으로 내림차순으로 가져온다. - LIMIT $start,$per_post
- 게시글 시작번호부터 $per_post개수만큼 가져온다.
4. 블럭당 페이지 출력
while($start_block<=$end_block){
//현재페이지는 페이지 클릭 안되게 하기
if($start_block==$page) {
echo "<a href='/board/board.php?page=$start_block' class='active'>$start_block</a>";
} else {
echo "<a href='/board/board.php?page=$start_block'>$start_block</a>";
}
$start_block++;
}
- 블럭의 시작페이지가 블럭의 마지막페이지와 같거나 작을 때 반복해준다
- 1블럭일 때, 1~5페이지 출력 2블럭일 때, 6~10페이지 출력 - 시작페이지와 현재 내 페이지가 같다면 효과를 주기 위해 if문 사용
- 1페이지에 있다면 1페이지 외에 다른페이지만 클릭 가능
5. 처음/이전/다음/끝 편의기능
✅글이 적다면 상관없지만 많아졌을 땐 불편함을 호소할 수 있기 때문에 구현했다.
<?php
//처음 블럭으로
if($current_block>1){
echo "<a href='/board/board.php?page=1'><<</a>";
}
//이전 블럭으로
if($current_block>1){
$pre_page = $start_block - 1;
echo "<a href='/board/board.php?page=$pre_page'><</a>";
}
//블럭당 페이지 출력
while($start_block<=$end_block){
//현재페이지는 페이지 클릭 안되게 하기
if($start_block==$page) {
echo "<a href='/board/board.php?page=$start_block' class='active'>$start_block</a>";
} else {
echo "<a href='/board/board.php?page=$start_block'>$start_block</a>";
}
$start_block++;
}
//다음 블럭으로
if($current_block<$total_block){
$next_page=$end_block + 1;
echo "<a href='/board/board.php?page=$next_page'>></a>";
}
//마지막 블럭으로
if($current_block<$total_block){
echo "<a href='/board/board.php?page=$total_page'>>></a>";
}
?>
- 처음 = 현재블럭이 1이상 즉, 2번째 블럭,3번째 블럭일 때만 젤 처음 페이지로 이동
- 이전 = 현재 블럭이 1이상 즉, 2번째 블럭,3번째 블럭일 때 전 블럭으로 이동
- 2번째 블럭 시작페이지는 6에서 -1을 해주면 5페이지 1번째 블럭으로 이동됨
- 3번째 블럭 시작페이지는 11에서 -1을 해주면 10페이지 2번째 블럭으로 이동됨 - 다음 = 현재블럭이 총 블럭 개수보다 작을 때 다음 블럭으로 이동
- 2번째 블럭 마지막페이지는 10에서 +1을 해주면 11페이지 3번째 블럭으로 이동됨
- 3번째 블럭 마지막페이지는 15에서 +1을 해주면 16페이지 4번째 블럭으로 이동됨 - 끝 = 현재블럭이 총 블럭 개수보다 작을 때 맨 끝 페이지로 이동
6. 테스트 해보자
✅먼저 테스트를 위한 50개의 게시글을 작성했다.
<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/board/dummy_data.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/php/db.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/php/session_guard.php';
$author = $_SESSION['user_id'];
for ($i = 1; $i <= 50; $i++) {
$title = "테스트글 $i";
$content = "이것은 테스트용 게시글입니다.";
$post_date = date("Y-m-d H:i:s");
$views = 0;
$likes = 0;
$sql = "
INSERT INTO board (title, content, author, post_date, views, likes)
VALUES ('$title', '$content', '$author', '$post_date', $views, $likes)
";
$mysqli->query($sql);
}
echo "더미 게시글 50개 삽입 끝";
?>
➡️삽입 성공!
✅>>(끝) 클릭해보기
➡️성공적으로 제일 끝페이지에 도달했다.
✅<<(처음) 클릭해보기
➡️성공적으로 제일 첫 페이지에 도달했다.
✅>(다음) 클릭해보기
➡️1번째 블럭에서 2번째 블럭으로 이동됐다.
✅<(이전) 클릭해보기
➡️다시 1번째 블럭으로 돌아온 것을 확인할 수 있다.
7. 최종코드
<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/php/db.php';
if(isset($_GET['page'])){
$page = $_GET['page'];
}else{
$page = 1;
}
$sql="SELECT * FROM board";
$result = $mysqli->query($sql);
$total_post = $result->num_rows;//총 게시글 수
$per_post = 5;//페이지당 보여줄 게시글 수
$start = ($page-1)*$per_post;//페이지당 보여줄 게시글 시작번호
$total_page = ceil($total_post/$per_post);//총 페이지 수
$per_block = 5;//한 블럭당 보여줄 페이지 수
$total_block = ceil($total_page/$per_block);//총 블럭 수
$current_block = ceil($page/$per_block);//현재 페이지가 속한 블럭
$start_block = ($current_block-1)*$per_block+1;//지금 블럭의 시작 페이지 번호
$end_block = min(($start_block + $per_block -1),$total_page);//지금 블럭의 마지막 페이지 번호
?>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>게시판</title>
<link rel="stylesheet" href="/CSS/basic.css">
<link rel="stylesheet" href="/CSS/board.css">
</head>
<body>
<header class="board_title">
<h1>Board</h1>
<div class="nav">
<a href="/board/board.php">회원게시판</a>
<a href="/pages/main.php">메인페이지</a>
<a href="/pages/mypage.php">마이페이지</a>
</div>
<hr>
</header>
<div class="write_btn1">
<a href="/board/board_write.php">글쓰기</a>
</div>
<table class="board_table">
<thead>
<tr>
<th>POST ID</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
<th>조회수</th>
<th id="emot">💌</th>
</tr>
</thead>
<tbody>
<?php
$sql_page = "SELECT * FROM board ORDER BY idx DESC LIMIT $start,$per_post";
$res_page = $mysqli->query($sql_page);
while($row = $res_page->fetch_assoc()){
?>
<tr>
<td><?= $row['idx']; ?></td>
<td><?= $row['title']; ?></td>
<td><?= $row['author']; ?></td>
<td><?= $row['post_date']; ?></td>
<td><?= $row['views']; ?></td>
<td><?= $row['likes']; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
<div class="page_wrapper">
<?php
//처음 블럭으로
if($current_block>1){
echo "<a href='/board/board.php?page=1'><<</a>";
}
//이전 블럭으로
if($current_block>1){
$pre_page = $start_block - 1;
echo "<a href='/board/board.php?page=$pre_page'><</a>";
}
//블럭당 페이지 출력
while($start_block<=$end_block){
//현재페이지는 페이지 클릭 안되게 하기
if($start_block==$page) {
echo "<a href='/board/board.php?page=$start_block' class='active'>$start_block</a>";
} else {
echo "<a href='/board/board.php?page=$start_block'>$start_block</a>";
}
$start_block++;
}
//다음 블럭으로
if($current_block<$total_block){
$next_page=$end_block + 1;
echo "<a href='/board/board.php?page=$next_page'>></a>";
}
//마지막 블럭으로
if($current_block<$total_block){
echo "<a href='/board/board.php?page=$total_page'>>></a>";
}
?>
</div>
</body>
</html>
페이징 기능까지 끝났다..이해하는데 좀 오래걸렸지만
그래도 막상 오래생각하고 만들어내니까 뿌듯함도 더 크다 ㅎㅎ🤣
'Web > Web 개발' 카테고리의 다른 글
파일 업로드/다운로드 기능 (0) | 2025.05.26 |
---|---|
게시판 읽기 기능 만들기 (0) | 2025.05.19 |
게시글 리스트 출력 만들기 (0) | 2025.05.13 |
게시글 쓰기 기능 만들기 (0) | 2025.05.09 |
마이페이지 회원정보 수정 기능 구현 (1) | 2025.04.26 |