Today I Learned …

[웹개발] 게시글 리스트 페이징 기능 본문

Web/APM

[웹개발] 게시글 리스트 페이징 기능

염베리 2021. 11. 1. 05:52

* 개인적인 공부 내용을 기록한 글입니다.


설명

저번에 게시글 리스트 출력을 다뤘으니

이번에는 페이징을 다뤄볼까 한다.

 

페이징에는 크게 두 가지의 목표가 있다.

 

1. 한 페이지 당 원하는 개수의 게시글을 출력하고 그때 그때 총 페이지 개수에 따라 페이지 번호를 출력해 링크를 타고 넘어다닐 수 있게끔 한다.

 

2. 페이지가 20개, 30개 된다면... 혹은 100개 쯤 된다면 페이지 번호 자체도 페이징해주는 편이 보기 편할 것이다. 이걸 보통 block이라고 부른다.

 

여기서는 먼저 1번을 다뤄본다.

 

최종 화면

클릭하면 확대됩니다.


게시글 리스트 페이징 기능 : 게시글 페이징

 

 

1. 먼저, 이전에 짜놨던 기본 게시글 리스트 출력 코드이다.

	//(윗 부분)...
        <?php
            $conn = mysqli_connect('localhost', 'choco', '7173', 'study_login');
            
            $sql = "SELECT * FROM board ORDER BY id DESC";
            $res = mysqli_query($conn, $sql);

            while($row = mysqli_fetch_array($res)){
        ?>
            <tbody>
                <tr align=center>
                    <td><?php echo $row['id'];?></td>
                    <td><a href="view.php?id=<?=$row['id']?>"><?php echo $row['title'];?></a></td>
                    <td><?php echo $row['name'];?></td>
                    <td><?php echo $row['written'];?></td>
                    <td><?php echo $row['hit'];?></td>
                    <td><?php echo $row['liked'];?></td>
                </tr>
            </tbody>
        <?php } ?>
    </table>
</body>
</html>

[1] 전체 게시글을 id를 기준으로 내림차순으로 정렬하고,

[2] while문을 통해 반복적으로 fetch하여 전체 목록을 출력하고 있음을 알 수 있다.

[3] 우리는 여기에 현재 위치한 페이지 번호에 따라 출력될 게시글을 정하는 규칙을 만들어줄 것이다.

 

 

2. 가장 먼저, 현재 페이지 번호를 변수에 할당해준다.

if(isset($_GET['page'])){
	$page = $_GET['page'];
} else {
	$page = 1;
}

[1] 페이지 번호를 넘어다닐 때는 GET 메소드를 사용할 것이기 때문에,

[2] GET으로 넘어올 page를 받아 $page에 할당해주고,

[3] GET으로 넘어온 page가 없을 경우 (= default 상태) 1페이지일 것이기 때문에 $page에 1을 할당해준다.

 

 

3. 게시글의 총 개수를 변수에 할당해준다.

$sql = "SELECT * FROM board";
$res = mysqli_query($conn, $sql);

$total_post = mysqli_num_rows($res);

[1] mysqli_num_rows(query) 함수를 사용해 게시글의 총 개수를 알아내 변수에 할당해준다.

[2] 나중에 총 페이지 개수에 따라 페이지 번호를 출력하기 위한 사전 작업이다.

 

 

4. 한 페이지 당 출력할 게시글의 개수를 정해준다.

$per = 5;

[1] 자신이 원하는대로 정해준다. 꼭 5개가 아니어도 상관없다.

 

 

5. 매 페이지를 시작할 게시글의 번호를 정해준다.

$start = ($page-1)*$per + 1;

[1] 조금 이해가 필요한 부분일 수 있지만 예시를 들어 생각해보면 된다.

[2] 만약 현재 페이지가 1페이지이고, 페이지 당 출력할 게시글이 5개라면, (1-1)*5 + 1 = 1 번부터 출력하면 된다.

[3] 만약 현재 페이지가 2페이지이고, 페이지 당 출력할 게시글이 5개라면, (2-1)*5 + 1 = 6 번부터 출력하면 된다.

[4] 만약 현재 페이지가 3페이지이고, 페이지 당 출력할 게시글이 5개라면, (3-1)*5 + 1 = 11 번부터 출력하면 된다.

[5] 이것을 일반화시키면 ($page-1)*$per + 1 이 된다.

* 여기서 말하는 '게시글의 번호' 란 게시글의 식별자 (= id) 를 말하는 것이 아니다.

* 내림차순이든 오름차순이든 게시글을 쭉 줄세웠을 때의 순서 번호를 말하는 것이다.

 

 

6. $start에서 1을 빼준다.

$start -= 1;

[1] limit를 사용해 결과값을 제한하여 결과적으로 게시글을 잘라줄 것이기 때문에,

[2] limit의 용법에 맞춰 시작값을 조정해준다.

[3] limit의 시작 행은 1이 아니라 0이기 때문에 $start에서 1을 빼주는 것이다.

 

 

7. 최종적으로 게시글 가져오기

$sql_page = "SELECT * FROM board ORDER BY id DESC limit $start, $per";
$res_page = mysqli_query($conn, $sql_page);

[1] ORDER BY id DESC

⇒ id를 기준으로 내림차순으로 가져온다.

[2] limit $start, $per

$start부터 시작해 $per개 가져온다.

 

 

8. 지금까지의 전체 코드이다. (게시글 정보 출력 포함)

<?php
	$conn = mysqli_connect('localhost', 'choco', '7173', 'study_login');

	if(isset($_GET['page'])){
		$page = $_GET['page'];
	} else {
		$page = 1;
	}

	$sql = "SELECT * FROM board";
	$res = mysqli_query($conn, $sql);

	$total_post = mysqli_num_rows($res);
	$per = 5;

	$start = ($page-1)*$per + 1;
	$start -= 1;

	$sql_page = "SELECT * FROM board ORDER BY id DESC limit $start, $per";
	$res_page = mysqli_query($conn, $sql_page);

	while($row = mysqli_fetch_array($res_page)){ ?>
		<tbody>
			<tr align=center>
				<td><?php echo $row['id'];?></td>
				<td><a style="color:purple;" href="view.php?id=<?=$row['id']?>"><?php echo $row['title'];?></a></td>
				<td><?php echo $row['name'];?></td>
				<td><?php echo $row['written'];?></td>
				<td><?php echo $row['hit'];?></td>
				<td><?php echo $row['liked'];?></td>
			</tr>
		</tbody>
<?php } ?>

게시글 리스트 페이징 기능 : 페이지 번호 출력

 

 

1. 총 페이지 개수에 따라 페이지 번호 출력하기

<?php
    
	$total_page = ceil($total_post / $per);
	$page_num = 1;
    
	while($page_num <= $total_page){
		if($page==$page_num){
			echo "<a style=\"color:purple;\" href=\"board.php?page=$page_num\">$page_num </a>";
		} else {
			echo "<a href=\"board.php?page=$page_num\">$page_num </a>"; }
		$page_num++;
	}
    
?>

[1] 총 페이지 개수는 ceil() 을 사용해 (총 게시글 개수 / 페이지 당 게시글 개수) 를 올림해준 값 으로 정한다.

[2] 총 게시글 개수가 11개 이고, 페이지 당 게시글 개수가 5개라면, 총 페이지는 나머지까지 3장이 나와야하기 때문이다.

[3] while문을 사용해 페이지 번호를 출력하고 올바른 링크를 걸어준다.

[4] 위 코드처럼 현재 페이지 숫자에는 색을 입혀주면 현재 페이지를 눈으로 쉽게 확인할 수 있다.

[5] 여기까지만 해도 정상적으로 페이징 기능이 수행된다.

 

 

1.  처음/이전/다음/끝 편의 기능을 포함한 전체 코드이다.

<?php
	if($page > 1){
		echo "<a href=\"board.php?page=1\">[처음] </a>";
	}
	if($page > 1){
		$pre = $page - 1;
		echo "<a href=\"board.php?page=$pre\">이전 </a>";
	}
    
	$total_page = ceil($total_post / $per);
	$page_num = 1;
    
	while($page_num <= $total_page){
		if($page==$page_num){
			echo "<a style=\"color:purple;\" href=\"board.php?page=$page_num\">$page_num </a>";
		} else {
			echo "<a href=\"board.php?page=$page_num\">$page_num </a>"; }
		$page_num++;
	}
    
	if($page < $total_page){
		$next = $page + 1;
		echo "<a href=\"board.php?page=$next\">다음 </a>";
	}
	if($page < $total_page){
		echo "<a href=\"board.php?page=$total_page\">[끝]</a>";
	}
?>

[1] 현재 페이지가 첫 페이지가 아니라면?

⇒ 첫 페이지로 가는 [처음]과 이전 페이지로 가는 [이전]을 출력한다.

[2] 현재 페이지가 마지막 페이지가 아니라면?

⇒ 마지막 페이지로 가는 [끝]과 다음 페이지로 가는 [다음]을 출력한다.

프로필사진
berry
FE Developer, loves React & better DX
Comments