페이징 기능 - board page
DATE : 2023/12/2
오늘은 4주차에 진행했던 Web Server에 이어서 게시판 페이지를 만들어 볼 것이다.
바로 본론으로 들어가기 전, 진행 상황을 다시 떠올려보자.
[ COMPLETED ]
: write 버튼으로 이동한 write_post page에서 사용자가 글을 작성하면 board Table에 저장
: 글 작성을 마친 후, 다시 index page로 돌아가면 board Table에 들어있는 정보로 게시판 구성
[ NEXT ]
: 게시판 목록에 있는 글을 하나 선택하면 해당 POST의 내용을 볼 수 있는 상세 페이지로 이동
: 찾고자 하는 데이터를 입력하면 지정된 카테고리에 한하여 게시물 정렬
: 게시물이 10개 이상 작성되면, 여러 페이지에 걸쳐 게시판 목록 제공 ( 페이징 )
이번 페이지에서는 우선, 페이징 기능부터 구현할 예정이다.
그럼 바로 코드로 넘어가 보자!!
[ index.php ]
<?php
session_start();
if($_SESSION['login_check'] != 1) {
header("location: login.html");
exit;
} else if($_SESSION['login_check'] == 1) {
require_once("jwt.php");
require_once("./db_connect.php");
$usr = getToken($_COOKIE['JWT'])['usr'];
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./css/index.css">
<title>Main page</title>
</head>
<body>
<div class="header">
<p><?php echo $usr;?>님</p>
<button id="mypage_btn">
My Page
</button>
</div>
<div class="container">
<div class="page_title">
BOARD
</div>
<div class="table">
<div class="funcs">
<form method="post">
<select name="order" id="order">
<option value="date" autofocus>Date</option>
<option value="author">Author</option>
<option value="title">Title</option>
<option value="hit">Hit</option>
</select>
<input type="text" placeholder="Search" class="search" name="search_value">
<input type="submit" value="Search" id="search_btn" name="submit">
</form>
<button id="write_btn">WRITE</button>
</div>
<table>
<?php
if(isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = 1;
}
if(isset($_POST['submit'])) {
$search_value = $_POST['search_value'];
$option = $_POST['order'];
}
if(isset($_POST['search_value'])) {
$sql = "SELECT * FROM board WHERE $option LIKE '%$search_value%' ORDER BY $option";
// $page = 1;
} else {
$sql = "SELECT * from board";
}
$res = mysqli_query($conn, $sql);
$cnt = mysqli_num_rows($res);
$post_per_page = 10;
$start = ($page - 1) * $post_per_page;
if(!$res) { //에러
echo "Error";
} else if($cnt == 0) { //Post 없음
echo "<tr><th>There is No Post</th></tr>";
} else {
echo "<tr><th></th><th>Title</th><th>Author</th><th>Date</th><th>Hit</th></tr>";
if(isset($_POST['search_value'])) {
$get_post_sql = "SELECT * FROM board WHERE $option LIKE '%$search_value%' ORDER BY $option LIMIT $start,$post_per_page";
} else {
$get_post_sql = "SELECT * FROM board ORDER BY date LIMIT $start,$post_per_page";
}
$get_post_res = mysqli_query($conn, $get_post_sql);
while($row = mysqli_fetch_array($get_post_res)) {?>
<tr class="article_row" id="article_row">
<th><?=$row['id'];?></th>
<th class="title"><a href="article.php?idx=<?=$row['id'];?>"><?=$row['title'];?></a></th>
<th><?=$row['author'];?></th>
<th><?=$row['date']?></th>
<th><?=$row['hit']?></th>
</tr>
<?php }} ?>
</table>
<div class="footer">
<?php
$total_page = ceil($cnt / $post_per_page);
$page_num = 1;
while($page_num <= $total_page) {
if($page_num == $page) {
echo "<strong>$page_num</strong>";
} else {
echo "<a href='index.php?page=$page_num'>$page_num</a>";
}
$page_num++;
}
?>
</div>
</div>
</div>
<script src="./btn.js"></script>
<script src="https://kit.fontawesome.com/5b18c6ebda.js" crossorigin="anonymous"></script>
</body>
</html>일단 가볍게 달라진 점을 먼저 언급해보면 전에는 JWT의 발행 여부로 로그인 여부를 확인했는데,
지금은 Session을 사용하고 있다는 정도?
자! 그럼 바-로 페이징 기능과 관련된 코드를 살펴보자.
위의 코드는 table tag 안에 작성된 PHP 코드이다.
순서대로 코드를 분석해보면
우선, $_GET에 KEY page가 존재하는 지 확인한다.
여기서 page 값이 무엇인지는 아래에서 확인할 수 있을 것이다!
만약 page 값이 존재하지 않는 다면 1을, 존재한다면 $_GET['page']를 변수 $page에 할당해준다.
그 다음 확인하는 값은 $_POST['submit]으로
이는 index page에서 게시물을 검색하기 위해 search 버튼을 클릭했을 경우,
form tag가 post method로 현재 경로에 전달하는 값이다.
즉 $_POST['submit']이 존재하는 지를 확인하는 건,
사용자가 검색 버튼을 눌렀는 지를 확인하는 절차인 것이다.
만약 사용자가 검색 기능을 사용했다면
검색 창에 입력한 값을 $search_value에, select tag에서 선택한 옵션을 $option에 할당한다.
사용자가 특정 게시물을 찾기 위해 어떤 값을 입력했다면
LIKE operator를 사용해 SQL을 작성하고 그렇지 않다면 그냥 모든 게시물을 가져오도록 한다.
케이스에 따라 작성해둔 SQL을 실행한 후, 꺼내온 게시물의 개수를 $cnt에 넣고
각 페이지 당 보여줄 게시물 개수를 $post_per_page에 할당해둔다.
다음으로 계산해야 하는 건, 몇 번째 게시물부터 현재 페이지에 띄워야 하는 지!
현재 페이지에 띄울 첫 번째 게시물 순서를 알아내는 것이다.
현재는 $_GET['page'] 값이 없기 때문에 $page는 1을 할당 받은 상태이고
이때의 $start 값은 0이 된다.
SQL을 실행하는 과정에서 문제가 발생했다면 Error를 출력하고
SQL 실행 결과, row가 0개 라면 There is No Post 문구를 출력하도록 처리한다.
if & else if문으로 처리한 경우가 아니라면 while문을 돌면서 게시판을 구성하도록 하는 데 이때,
위에서 했던 거 처럼 search_value의 여부로 각 상황에 알맞은 Query가 실행될 수 있도록 처리한다.
실행한 Query를 보면 위에서 구한
$start 값을 사용해 총 10개의 게시물 정보만 가져오도록 작성한 걸 확인할 수 있다.
참고로 Query에 사용된 limit은
start 위치부터 cnt 개수 만큼만 결과를 가져오도록 개수를 제한하는 기능을 담당한다.
총 게시물 개수를 페이지 당 보여줄 게시물의 개수로 나누면,
우리가 꺼내온 게시물을 보여주기 위해 몇 개의 페이지가 필요한 지 알아낼 수 있다.
필요한 페이지 개수를 알아냈다면 while문을 돌면서
현재 페이지와 $page_num이 일치하는 경우에는 그 숫자를 strong tag로 처리하고
그 밖의 페이지는 숫자를 클릭했을 때, 해당 페이지로 이동할 수 있도록 a tag로 처리한다.
이때 a tag의 href 값을 보면
page parameter에 클릭한 페이지 번호가 전달되는 걸 볼 수 있다.
즉, 맨 처음에 확인했던 $_GET['page'] 는
페이징 기능으로 제공된 페이지 순번 링크가 클릭 되는 경우에만 생성되는 값으로
클릭 되지 않은 경우(ex. 사용자가 로그인을 마친 후, index page로 막 접근한 경우)에는
첫 번째 페이지를 제공해야 하기 때문에 $page 값을 1로 설정했던 것이다.
이렇게 해서 완성된 페이지를 확인해보면~.~

게시판 하단에 제공되는 페이지 버튼을 누르면

다음 게시물 목록이 보이는 페이지로 이동하는 걸 볼 수 있다!
다시 첫 번째 페이지로 이동하고 싶다면 " 1 "을 클릭하면 간단히 이동 가능 😄
하단에 제공되는 페이지 번호를 클릭함으로써 다음 페이지로 넘어갈 수 있고
페이지 당 게시물의 개수를 제한해 깔끔하게 페이지를 구성할 수 있게 되었다!! 👍
아주 큰 산을 하나 넘긴 느낌이라 이 기분을 만끽하고 싶지만 🤗
아직 해야 하는 게 많이 남았다..! 다음으로 정렬 & 검색 기능을 구현하러 가보자 😩
Last updated