[7주차] 게시판 구현 #4 - 페이징 만들기
이 구현 코드는 대부분
https://blog.naver.com/bgpoilkj/221265496444
이 블로그를 참조하여 작성되었습니다.
저번에 구현시킨 것에 이어서 게시판 페이징 하는 걸 해봅시다.
우선, noticeboard.php 를 좀 수정해볼게여
noticeboard.php
<!doctype html>
<?php
session_start();
$con = mysqli_connect('localhost','root','1234','test');
$query = "SELECT * FROM board";
$result = $con->query($query);
?>
<style>
#page_num {
font-size: 14px;
margin-left: 260px;
margin-top:30px;
}
#page_num ul li {
float: left;
margin-left: 10px;
text-align: center;
}
.fo_re {
font-weight: bold;
color:red;
}
.space {
margin-left:250px;
}
</style>
<head>
<meta charset="UTF-8">
<title>게시판</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.7/dist/umd/popper.min.js" integrity="sha384-zYPOMqeu1DAVkHiLqWBUTcbYfZ8osu1Nd6Z89ify25QV9guujx43ITvfi12/QExE" crossorigin="anonymous"></script>
<div id="board_area">
<h1>자유게시판</h1>
<div>원하는 내용을 자유롭게 작성해주세요!</div>
<table class="table">
<thead>
<tr>
<th width="70">번호</th>
<th width="300">제목</th>
<th width="130">글쓴이</th>
<th width="120">작성일</th>
<th width="50">조회수</th>
<th width="50">추천수</th>
</tr>
</thead>
<?php
if(isset($_GET['page'])){
$page = $_GET['page'];
}else{
$page = 1;
}
$row_num = mysqli_num_rows($result); //게시판 총 레코드 수
$list = 5; //한 페이지에 보여줄 개수
$block_ct = 5; //블록당 보여줄 페이지 개수
$block_num = ceil($page/$block_ct); // 현재 페이지 블록 구하기
$block_start = (($block_num - 1) * $block_ct) + 1; // 블록의 시작번호
$block_end = $block_start + $block_ct - 1; //블록 마지막 번호
$total_page = ceil($row_num / $list); // 페이징한 페이지 수 구하기
if($block_end > $total_page) $block_end = $total_page; //만약 블록의 마지박 번호가 페이지수보다 많다면 마지박번호는 페이지 수
$total_block = ceil($total_page/$block_ct); //블럭 총 개수
$start_num = ($page-1) * $list; //시작번호 (page-1)에서 $list를 곱한다.
$query2="SELECT * FROM board order by number desc limit $start_num,$list;
$result2 = $con->query($query2);
while($board = $result2->fetch_array()){
$title=$board["title"];
if(strlen($title)>30)
{
$title=str_replace($board["title"],mb_substr($board["title"],0,30,"utf-8")."...",$board["title"]);
}
$sql3 = mq("select * from reply where con_num='".$board['idx']."'");
$rep_count = mysqli_num_rows($sql3);
?>
<tbody>
...이하 생략
<!---페이징 넘버 --->
<div id="page_num">
<ul>
<?php
if($page <= 1)
{ //만약 page가 1보다 작거나 같다면
echo "<li class='fo_re'>처음</li>"; //처음이라는 글자에 빨간색 표시
}else{
echo "<li><a href='?page=1'>처음</a></li>"; //알니라면 처음글자에 1번페이지로 갈 수있게 링크
}
if($page <= 1)
{ //만약 page가 1보다 작거나 같다면 빈값
}else{
$pre = $page-1; //pre변수에 page-1을 해준다 만약 현재 페이지가 3인데 이전버튼을 누르면 2번페이지로 갈 수 있게 함
echo "<li><a href='?page=$pre'>이전</a></li>"; //이전글자에 pre변수를 링크한다. 이러면 이전버튼을 누를때마다 현재 페이지에서 -1하게 된다.
}
for($i=$block_start; $i<=$block_end; $i++){
//for문 반복문을 사용하여, 초기값을 블록의 시작번호를 조건으로 블록시작번호가 마지박블록보다 작거나 같을 때까지 $i를 반복시킨다
if($page == $i){ //만약 page가 $i와 같다면
echo "<li class='fo_re'>[$i]</li>"; //현재 페이지에 해당하는 번호에 굵은 빨간색을 적용한다
}else{
echo "<li><a href='?page=$i'>[$i]</a></li>"; //아니라면 $i
}
}
if($block_num >= $total_block){ //만약 현재 블록이 블록 총개수보다 크거나 같다면 빈 값
}else{
$next = $page + 1; //next변수에 page + 1을 해준다.
echo "<li><a href='?page=$next'>다음</a></li>"; //다음글자에 next변수를 링크한다. 현재 4페이지에 있다면 +1하여 5페이지로 이동하게 된다.
}
if($page >= $total_page){ //만약 page가 페이지수보다 크거나 같다면
echo "<li class='fo_re'>마지막</li>"; //마지막 글자에 긁은 빨간색을 적용한다.
}else{
echo "<li><a href='?page=$total_page'>마지막</a></li>"; //아니라면 마지막글자에 total_page를 링크한다.
}
?>
</ul>
</div>
<div id="write_btn">
<a href="./write.php"><button itype="button" class="btn btn-outline-success space">글쓰기</button></a>
</div>
</div>
</body>
</html>
$row_num을 구해서 게시판 총 갯수를 구한다.
이 갯수를 구할 땐 SQL 쿼리문을 "SELECT * FROM board" 로 limit를 걸지 않고 한 번에 구하는 것이 핵심이다.
그리고 현재 게시글 총 수가 많지 않기 때문에 한 페이지에 보여줄 게시글 수를 $list = 5, 즉 5개로 정한다.
총 전체 페이지는 ceil 함수를 이용한다. ceil 함수는 결과값을 무조건 올림으로 측정하는데,
$total_page = ceil ($row_num/$list); 라고 하면 긁어온 게시판 개수를 5로 나눠준다. 12개를 긁어왔는데 5로 나누면 2.4 되므로 ceil을 거치고 나면 3 페이지로 측정하는 것이다.
현재 페이지 블록은 GET방식으로 받을 $page를 $block_ct 인 5로 나눠준 값을 ceil 함수를 통해 올려서 측정한다.
1 페이지라면 그대로 1/ 5 를 계산한 뒤 올려 1이 그대로 나오고
6 페이지라면 6/5를 계산한 뒤 올려 1이 나오게 된다.
위 코드를 저장하고 웹에서 한번 띄워보자.
정렬이 올바르지 않아 보기가 좋아 보이지가 않습니다.
css를 추가해서 깔끔하게 만들어보겠습니다.
link 태그를 한번 더 써서 bootstrap 밑에 적어보았는데 중첩이 되지 않는 것 같았습니다.
그래서 style 태그를 열어 원하는 css 코드를 써넣었습니다.
1번 페이지에 위치해 있을 때, 처음과 마지막이 붉게 변하는 것이 적용되었고 중앙 정렬도 잘 적용 되었네요
그런데 페이징과 글쓰기 버튼이 너무 딱 달라붙어있는 것 같아 보기가 별로입니다.
공간을 만들어주기 위해 space style을 추가합니다. 현재 코드에선 style 태그 안에 넣었습니다.
.space {
margin-left:10px;
}
글쓰기 버튼에 space class속성을 바로 부여합니다.
class는 계속 띄어쓰기로 이어붙이면 여러개의 class를 부여할 수 있습니다.
한번 띄어서 space 클래스를 부여합니다.
10px만큼의 margin-left가 적용되어 떨어져있는 걸 볼 수 있습니다.
값을 좀 더 줘볼까요?
과감하게 margin-left에 250px 값을 줬습니다.
글쓰기 버튼이 아주 예쁘게 들어가있는 것을 볼 수 있습니다!
여기서 현재 게시글이 3개 정도 있으니 3개만 더 써서 2 페이지를 만들어보겠습니다.
페이징 테스트 하기 위해 아무 글이나 3개 만들었습니다.
코딩한대로 2페이지가 생성되었습니다.
2를 누르면 2 블록과 마지막이 붉게 변하고 2페이지로 잘 이동합니다.
그리고 1 페이지를 벗어났더니 '이전' 버튼이 생겼습니다.
근데 예상했던 것처럼 글쓰기 버튼을 그냥 px로 줬더니 페이지가 늘어날 때마다 다음 줄로 넘어가는 현상이 발생합니다.
따라서 float : right 를 줘서 오른쪽 정렬로 바꿔줍시다.
이러면 아무리 페이징블록이 많아져도 오른쪽 정렬이 그대로 유지될 것입니다.
.space {
float : right;
}
이전 버튼도 테스트해보니 잘 작동합니다.
그리고 만드는 김에 text-align: center 속성도 줘서 중앙 정렬 되게 만들어 깔끔하게 했습니다.
하기 전보다 깔끔해진 것 같습니다.