1

PHP - 게시판 제작 10 - 페이징

PHP - 게시판 제작 10 - 페이징

노아의 블로그

    목차
반응형

저번 시간에는 게시판 검색까지 제작했습니다.
하지만 여기서 문제점이 있습니다. 게시글이 많아진다면 계속해서 스크롤을 내려야 한다는 문제가 있습니다.
글들을 페이지로 나눠서 보여줍시다.
 

 
이런식으로 말이죠!
 
페이징을 하려면 limit를 사용해야합니다.
 
limit에 뭐가있었죠? 
첫번째 칸은 몇번째 행부터 출력할 것인가를 의미합니다.
두번째 칸은 출력할 데이터 양을 의미합니다.
즉 limit 0,10 은 0번째부터 10개의 데이터를 가져와. 이런 느낌이죠.
 
그러면 1페이지는 limit 0,10이고 
2 페이지는 limit 10,10 이네요.
3 페이지는? limit 20,10이겠네요! 
 
규칙이 보이시나요? 10씩 늘어나고있습니다.
 
즉 (페이지-1) x 10 을 하면 limit에 들어가는 값을 구할 수 있습니다.
 
직접 코드를 작성 해 봅시다.
 

$page = $_GET['page'];
$limitpage = ($page - 1) * 10;
$max = 10;

get 방식으로 page 파라미터를 받아서 limit절에 들어갈 값을 계산합니다.
 
계산된 값으로 쿼리문을 제작합시다.
 

<?php
$search = $_GET['search'];
$page = $_GET['page'];
$limitpage = ($page - 1) * 10;
$max_content = 10;

echo $limitpage;
$encoded_text = htmlspecialchars($search);

if($search){$sql = "select * from board where title like '%$search%'";}
else{$sql = "select * from board limit $limitpage,$max";}


$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
        while($row = mysqli_fetch_assoc($result)) {
        echo "<a href='read.php?bno=" . $row['bno'] . "'>" . $row['title'] . "</a>";
        echo "<br>";
    }

}
else{
	echo"<p>no search results for $encoded_text </p>";
}
?>

 
이제 페이지 파라미터를 입력하고 변경 해 봅시다.
 
<1 페이지>

<2 페이지>

페이지마다 각각 다른 결과가 나오네요!
 
여기까지는 쉽습니다.
하지만 아직 한발 남았죠.
 
페이지 1 2 3 4 5 표시되는 것을 만들어야 합니다.
 
이제 좀 수학적인 부분이 나옵니다. (프로그래밍에서 수학은 필요합니다...ㅠ)
 
일단 첫 페이지와 마지막 페이지를 구해야합니다.
 
첫 페이지는 무조건 마지막 페이지 - (최대페이지 - 1)입니다.
마지막 페이지는 들어온 값에 따라 계산합니다.
 
1~5 는 마지막이 무조건 5입니다. 6~10은 마지막 페이지가 무조건 10입니다.
 
이럴때는 나누기를 하면 됩니다.  
0을 5로나누면 0
1을 5로 나누면 0.2
4를 5로 나누면 0.8 
 
6을 5로 나누면 1.2
 
12를 5로 나누면 2.2 
 
규칙이 보이시나요? 네. 페이지가 올라가면 올림이 된다는 것 입니다.
 
이 올림을 이용하는것이죠.
일단 소수점은 전부 버립니다.
그리고 정수 부분에 +1을 해줍니다 그것을 5로 곱하면?
최대 페이지가 나오게 되네요.
 
1페이지의 최대 페이지 값 1*5 = 5
2페이지의 최대 페이지 값 2x5 = 10
3페이지의 최대 페이지 값 3x5 =15
 
쉽죵? 나눗셈만 잘 이해하고 계신다면 페이지 처리를 이해 할 수 있습니다.
 
이제 코드로 만들어 봅시다.

<?php
$search = $_GET['search'];
$page = $_GET['page'] - 1; //page
$maxpagecount = 5; //pagecount


$maxpage= floor($page / $maxpagecount + 1) * 5; //max page

$lowpage= $maxpage - ($maxpagecount - 1); //lowpage

echo "maxpage : " . $maxpage . "<br>";
echo "lowpage : " . $lowpage . "<br>";

이런식으로 만들 수 있습니다.
 

현재 페이지가 1일때 제일 작은 페이지는 1이고 제일 큰 페이지는 5이네요. 그럼 페이지를 한번 넘겨볼까요?

굿! 페이지가 넘어가서 6~10으로 되었습니다.
마지막으로, 14를 입력해 볼까요?
 

정상적으로 출력이 되었습니다. 
이제 "진짜" 페이지를 구해야 합니다..무슨뜻이냐!
 
지금 같은 경우에는 사용자가 입력한 페이지의 기준으로 low,max 페이지를 구성합니다.
하지만 게시물이 없을경우
페이지를 더이상 보여주지 말아야 합니다.
그러니 페이지의 갯수를 기준으로 max 페이지를 구해야 한다는 소리입니다.
 
페이지의 갯수는 무엇일까요.
여기서도 나눗셈이 등장하죠.
전체 게시물을 한 페이지당 출력할 게시물로 나누면 페이지의 갯수가 나옵니다.
 
게시물의 수는 DataBase에서 Count 함수로 구합니다.
Select count(*) as count from board;
 

$sql = "select count(*) as count from board";
$result = mysqli_query($conn, $sql);
$row = mysqli_fetch_assoc($result);
$count = $row['count'];

$real_max_page = ceil($count / $max_content);

if($max_page > $real_max_page){$max_page = $real_max_page;}

 
이렇게 전체 게시물과 한 페이지당 출력하는 게시물의 수를 나누어서
ceil 함수로 올림 처리를 합니다. 그 이유는 소수점 자리가 있다면 게시물이 있다는 소리거든요. 그니까 페이지를 올려야죠.
아무튼 이렇게 진짜 페이지를 구합니다.
 
이제 페이지 구하기는 끝났습니다.
 
프론트에서 리스트를 띄워봅시다.
 
프론트 작업은 chat gpt에게 맡기세요 ~~
 

<style>
    .pagination {
      display: flex;
      justify-content: center;
      align-items: center;
      list-style-type: none;
      padding: 0;
    }
    .pagination li {
      margin: 0 5px;
    }
    .pagination li a {
      text-decoration: none;
      padding: 5px 10px;
      border: 1px solid #ccc;
      border-radius: 5px;
    }
    .pagination li a.active {
      background-color: #ccc;
      color: white;
    }
  </style>

이러한 스타일을 제시해 주었네요.
html head 태그에 이 태그를 삽입합니다.
 
이제 이 스타일 css를 가지고 버튼을 만들어봅시다.
 

<ul class="pagination">
<?php for ($i = $low_page; $i <= $max_page; $i++){?>
    <li><a href=/board/list.php/?page=<?php echo $i?> class="page-number"><?php echo $i?></a></li><?php }?>

  </ul>

하단에 이러한 코드를 추가합니다.
class는 스타일을 적용하기 위해 설정한것이고 
for문을 돌려서 low page부터 max page까지 페이지 리스트를 생성합니다.

페이지 하단에 이러한 페이지 리스트가 생겼으면 정상적으로 처리되었습니다.
이제 버튼을 눌러 페이지가 정상적으로 바뀌는지 확인 해 봅시다.
 

정상적으로 처리되었습니다.
하지만 아직 하나가 남았죠.
바로 이전과 다음 버튼입니다. 이것은 간단합니다.
 
먼저 이전 페이지는 low page가 1이 아니면 어디서나 존재합니다.
그러므로 조건식을 low page > 1 으로 처리합니다.
 
다음 페이지는 기본적으로 구한 max page가 real max page보다 작은 경우 다음 데이터가 있겠죠.
 

$prev = $low_page > 1;
$next = $max_page < $real_max_page;

이런식으로 처리합니다.
 
이제 다시 프론트로 오죠.
 

<ul class="pagination">
<?php if($prev) { ?> <li><a href=/board/list.php/?page=<?php echo $low_page - 1?> class="previous">이전</a></li>  <?php } ?>

<?php for ($i = $low_page; $i <= $max_page; $i++){?>
    <li><a href=/board/list.php/?page=<?php echo $i?> class="page-number"><?php echo $i?></a></li><?php }?>
<?php if($next) { ?> <li><a href=/board/list.php/?page=<?php echo $max_page + 1?> class="previous">다음</a></li>  <?php } ?>
  </ul>

이런식으로 조건에 맞게 버튼이 생성되고 
이전 페이지를 누르면 low page - 1번 페이지로 이동
다음 페이지를 누르면 max_page + 1번 페이지로 이동하면 완성입니다.
 

이렇게 첫 번째 페이지에는 이전 버튼이 없고 
다음 버튼을 클릭시 
 

게시물이 더 없으니까 9번 까지만 출력되고 다음 버튼이 없고 이전 버튼이 생긴 모습입니다.
 
이제 처리는 끝났습니다.
 
마지막으로 프론트 처리만 간단히 해주면?
 

<ul class="pagination">
<?php if($prev) { ?> <li><a href=/board/list.php/?page=<?php echo $low_page - 1?> class="previous">이전</a></li>  <?php } ?>

<?php for ($i = $low_page; $i <= $max_page; $i++){?>
    
    <?php if($page + 1 == $i){ ?> <li><a href=/board/list.php/?page=<?php echo $i?> class="page-number active"><?php echo $i?></a></li> 
    <?php  }
    else { ?> <li><a href=/board/list.php/?page=<?php echo $i?> class="page-number"><?php echo $i?></a></li>
     <?php } } ?>
<?php if($next) { ?> <li><a href=/board/list.php/?page=<?php echo $max_page + 1?> class="previous">다음</a></li>  <?php } ?>
  </ul>

이런식으로 사용자가 현재 보고있는 페이지를알 수 있게 표시가 됩니다...

자야되서 너무 후다닥 빨리 끝낸 것 같네요. 나중에  보기 쉽게 고쳐야겟..
 

<?php include "../connect.php"; ?>
<?php
$search = $_GET['search'];
$page = $_GET['page'] - 1; //page
$max_pageCount = 5; //pagecount
$max_content = 5;

$max_page= floor($page / $max_pageCount + 1) * 5; //max page

$low_page= $max_page - ($max_pageCount - 1); //lowpage

$sql = "select count(*) as count from board";
$result = mysqli_query($conn, $sql);
$row = mysqli_fetch_assoc($result);
$count = $row['count'];

$real_max_page = ceil($count / $max_content); 

$prev = $low_page > 1;
$next = $max_page < $real_max_page;

if($max_page > $real_max_page){$max_page = $real_max_page;} 

echo $low_page;




$limitpage = ($page - 1) * 10;

$encoded_text = htmlspecialchars($search);
?>

<!DOCTYPE html>
<head>
  
  <style>
    .pagination {
      display: flex;
      justify-content: center;
      align-items: center;
      list-style-type: none;
      padding: 0;
    }
    .pagination li {
      margin: 0 5px;
    }
    .pagination li a {
      text-decoration: none;
      padding: 5px 10px;
      border: 1px solid #ccc;
      border-radius: 5px;
    }
    .pagination li a.active {
      background-color: #ccc;
      color: white;
    }
  </style>
</head>

<body>
	<form action="" method ="get" id=search_form onsubmit="return submitevent();"> 
		<input type="search" name = "search" id = "search" value = "<?php echo $encoded_text; ?>">
		<input type="submit">
	</form>
	<script>
	function submitevent(){
		var search = document.getElementById("search").value;
		  if(search.includes("alert")){
		  alert("You cannot enter that character.");
		  return false;
		  
  		}
  		else{return true;}
	
	}
	
	</script>
	
	<?php
	if($search){$sql = "select * from board where title like '%$search%'";}
else{$sql = "select * from board limit " . $page * $max_content . ",$max_content";}


$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
        while($row = mysqli_fetch_assoc($result)) {
        echo "<a href='read.php?bno=" . $row['bno'] . "'>" . $row['title'] . "</a>";
        echo "<br>";
    }

}
else{
	echo"<script>alert('no search results for $encoded_text'); </script>";
}



?>

<ul class="pagination">
<?php if($prev) { ?> <li><a href=/board/list.php/?page=<?php echo $low_page - 1?> class="previous">이전</a></li>  <?php } ?>

<?php for ($i = $low_page; $i <= $max_page; $i++){?>
    
    <?php if($page + 1 == $i){ ?> <li><a href=/board/list.php/?page=<?php echo $i?> class="page-number active"><?php echo $i?></a></li> 
    <?php  }
    else { ?> <li><a href=/board/list.php/?page=<?php echo $i?> class="page-number"><?php echo $i?></a></li>
     <?php } } ?>
<?php if($next) { ?> <li><a href=/board/list.php/?page=<?php echo $max_page + 1?> class="previous">다음</a></li>  <?php } ?>
  </ul>

  
</body>

 
전체코드입니다.

웹 개발에서 초심자가 제일 힘들때가 아마 페이징,검색,인덱스 등등이죠.
물론 저도 초보입니다.
다들 화이팅 하자구요!!
 
 

반응형