Bomb Kirby Running

MySQL&PHP

PHP 게시판 페이지 만들기 (검색)

^. ̫ .^ 2023. 5. 1. 12:11

728x90

PHP 게시판에서 검색했을 경우의 페이지를 만들었습니다.

전체적인 구조는 board.php와 동일합니다.

 

게시글 검색 php

<?php
    include "../connect/connect.php";
    include "../connect/session.php";
    if(isset($_GET['page'])){
        $page = (int) $_GET['page'];
    } else {
        $page = 1;
    }

    $searchKeyword = $_GET['searchKeyword'];
    $searchOption = $_GET['searchOption'];
    $searchKeyword = $connect -> real_escape_string(trim($searchKeyword));
    $searchOption = $connect -> real_escape_string(trim($searchOption));
    $sql = "SELECT b.boardID, b.boardTitle, b.boardContents, m.youName, b.regTime, b.boardView FROM board b JOIN members m ON(b.memberID = m.memberID) ";
    switch($searchOption){
        case "title":
            $sql .= "WHERE b.boardTitle LIKE '%{$searchKeyword}%' ORDER BY boardID DESC ";
            break;
        case "content":
            $sql .= "WHERE b.boardContents LIKE '%{$searchKeyword}%' ORDER BY boardID DESC ";
            break;
        case "name":
            $sql .= "WHERE m.youName LIKE '%{$searchKeyword}%' ORDER BY boardID DESC ";
            break;
    }

    $result = $connect -> query($sql);
    $totalCount = $result -> num_rows;
?>

isset부분을 위로 올려주었습니다.

현재 페이지 번호를 전달하기 위해 GET 방식으로 전달된 'page' 파라미터가 있는지를 확인합니다.

 'page' 파라미터 값을 정수형으로 형변환하여 변수 $page에 할당하여 페이지 번호를 가져옵니다.

$page 변수에 1을 할당합니다 페이지 번호가 전달되지 않았을 때 기본값으로 첫 페이지를 설정할 수 있습니다.

GET 방식으로 전달된 검색어와 검색 옵션을 받아옵니다.

real_escape_string 함수를 사용하여 SQL Injection 공격을 방지하고, trim 함수를 사용하여 문자열 양 끝의 공백을 제거합니다.

JOIN 절을 사용하여  게시판 정보와 회원 정보를 연결하여 게시판 작성자의 이름 정보를 가져옵니다.

스위치 문을 사용해서 검색 옵션을 title일 경우 검색 키워드가 포함된 boardTitle을,  content일 경우 검색 키워드가 포함된 boardContents를,  name일 경우 검색 키워드가 포함된 회원에 등록된  youName을 내림차순으로 불러옵니다.

검색 결과의 총 개수를 가져옵니다.

총 갯수를 가져오기 위해 행된 쿼리문에서 반환된 행 수를 반환하는 num_rows 함수를 사용합니다. 

 

총 검색 건 수

        <p class="intro__text">
            웹디자이너, 웹 퍼블리셔, 프론트앤드 개발자를 위한 게시판입니다.<br>
            총 <em><?=$totalCount?></em>건의 게시물이 검색되었습니다.
        </p>

intro_text 밑에 검색된 글의 건 수를 구해주었습니다.

위에 isset을 올려줬기 때문에 totalCount의 값을 구할 수 있습니다.

<?=?>는 php의 약식입니다.

 

php로 테이블 만들기

<?php
    $viewNum = 10;
    $viewLimit = ($viewNum * $page) - $viewNum;
    $sql .= "LIMIT {$viewLimit}, {$viewNum}";
    $result = $connect -> query($sql);
    if($result){
        $count = $result -> num_rows;
        if($count > 0){
            for($i=0; $i<$count; $i++){
                $info = $result -> fetch_array(MYSQLI_ASSOC);
                echo "<tr>";
                echo "<td>".$info['boardID']."</td>";
                echo "<td><a href='boardView.php?boardID={$info['boardID']}'>".$info['boardTitle']."</a></td>";
                echo "<td>".$info['youName']."</td>";
                echo "<td>".date('Y-m-d', $info['regTime'])."</td>";
                echo "<td>".$info['boardView']."</td>";
                echo "</tr>";
            }
        } else {
            echo "<tr><td colspan='5'>게시글이 없습니다.</td></tr>";
        }
    }
?>

$viewNum 변수에 한 페이지에 보여줄 게시글의 수를 정합니다.

$viewLimit 변수에 ($viewNum * $page) - $viewNum 으로  현재 페이지에서 보여줄 게시글의 시작 위치를 계산합니다.

, $sql 변수에 LIMIT 절을 추가하여 $viewLimit 값부터 $viewNum 개수만큼의 게시글을 가져오도록 합니다.

$result 변수에는 쿼리 결과를 저장합니다.

쿼리 결과가 있을 경우, num_rows() 함수를 이용해 가져온 게시글 수를 구하고, 가져온 게시글의 수가 0보다 큰 경우, for 문을 사용하여 게시글 정보를 테이블 형태로 HTML 코드로 출력합니다.

fetch_array() 함수를 사용하여 각각의 게시글 정보를 가져와서 출력합니다.

만약 가져온 게시글이 없을 경우, "게시글이 없습니다." 메시지를 출력합니다.

 

페이지 넘김

<?php
    //총 페이지 갯수
    $boardTotalCount = ceil($totalCount/$viewNum);

    //1 2 3 4 5 6 7 8 9 10
    $pageView = 4;
    $startPage = $page - $pageView;
    $endPage = $page + $pageView;

    //처음/마지막 페이지 초기화
    if($startPage < 1) $startPage = 1;
    if($endPage >= $boardTotalCount) $endPage = $boardTotalCount;

     //처음, 이전
     if($page !== 1 && $boardTotalCount !=0 && $page <= $boardTotalCount){
        echo "<li><a href='boardSearch.php?page=1&searchKeyword={$searchKeyword}&searchOption={$searchOption}'>처음으로</a></li>";
        $prevPage = $page - 1;
        echo "<li><a href='boardSearch.php?page={$prevPage}&searchKeyword={$searchKeyword}&searchOption={$searchOption}'>이전</a></li>";
    }

    // 페이지
    for($i=$startPage; $i<=$endPage; $i++){
        $active = "";
        if($i == $page) $active = "active";
        if($page <= $boardTotalCount){
            echo "<li class='{$active}'><a href='boardSearch.php?page={$i}&searchKeyword={$searchKeyword}&searchOption={$searchOption}'>{$i}</a></li>";
        }
    }
    // 마지막으로/ 다음
    if($page != $boardTotalCount && $page <= $boardTotalCount){
        $nextPage = $page +1;
        echo "<li><a href='boardSearch.php?page={$nextPage}&searchKeyword={$searchKeyword}&searchOption={$searchOption}'>다음</a></li>";
        echo "<li><a href='boardSearch.php?page={$boardTotalCount}&searchKeyword={$searchKeyword}&searchOption={$searchOption}'>마지막으로</a></li>";
    }
?>

먼저, 전체 페이지 갯수를 구하기 위해 총 게시글 수($totalCount)를 페이지당 보여줄 게시글 수($viewNum)로 나누어 올림 처리(ceil())합니다. 이렇게 구한 전체 페이지 수를 $boardTotalCount에 저장합니다.

현재 페이지를 기준으로 페이징 바를 출력하기 위해 $pageView만큼 앞 뒤로 범위를 설정합니다.

이 범위를 $startPage$endPage에 저장합니다.

시작 페이지가 1보다 작거나, 마지막 페이지가 전체 페이지 수보다 크다면 시작 페이지는 1, 마지막 페이지는 전체 페이지 수가 되도록 초기화합니다.

처음과 이전 버튼을 출력합니다.

만약 현재 페이지가 1이 아니고, 전체 페이지 수가 0이 아니며, 현재 페이지가 전체 페이지 수보다 작거나 같다면 "처음으로" 버튼과 이전 버튼을 출력합니다.

이전 버튼은 $prevPage로 현재 페이지에서 1을 빼서 만듭니다.

$startPage부터 $endPage까지 for문을 돌며, 페이지 번호를 출력합니다. 만약 현재 페이지와 동일하다면, 해당 페이지는 활성화($active) 상태로 출력합니다.

다음 버튼과 마지막으로 버튼을 출력합니다.

만약 현재 페이지가 마지막 페이지가 아니고, 현재 페이지가 전체 페이지 수보다 작거나 같다면 다음 버튼과 마지막으로 버튼을 출력합니다.

다음 버튼은 $nextPage로 현재 페이지에서 1을 더해서 만듭니다

. 마지막으로 버튼은 전체 페이지 수를 이용합니다.

모든 버튼은 $searchKeyword$searchOption을 함께 GET 방식으로 전달합니다.

 

전체코드

<?php
    include "../connect/connect.php";
    include "../connect/session.php";

    $sql = "SELECT count(boardID) FROM board";
    $result = $connect -> query($sql);

    $boardTotalCount = $result -> fetch_array(MYSQLI_ASSOC);
    $boardTotalCount = $boardTotalCount['count(boardID)'];
?>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PHP 블로그 만들기</title>

    <?php include "../include/head.php" ?>
</head>
<body class="gray">
    <?php include "../include/skip.php" ?>
    <!-- //skip -->

    <?php include "../include/header.php" ?>
    <!-- // header -->

    <main id="main" class="container">
    <div class="intro__inner center bmStyle">
            <picture class="intro__images">
                <source srcset="../assets/img/board01.png, ../assets/img/board01@2x.png 2x, ../assets/img/board01@3x.png 3x" />
                <img src="../assets/img/board01.png" alt="회원가입 이미지">
            </picture>
            <h2>게시판</h2>
            <p class="intro__text">
                웹 디자이너, 웹 퍼블리셔, 프론트 엔드 개발자를 위한 게시판입니다.<br>
                관련된 문의사항은 여기서 확인하세요!
            </p>
        </div>
        <!-- //intro__inner -->
        <div class="board__inner">
            <div class="board__search">
                <div class="left">
                    * 총 <em><?=$boardTotalCount?></em>건의 게시물이 등록되어 있습니다.
                </div> 
                <div class="right">
                    <form action="boardSearch.php" name="boardSearch" method="get">
                        <fieldset>
                            <legend class="blind">게시판 검색 영역</legend>
                            <input type="search" name="searchKeyword" id="searchKeyword" placeholder="검색어를 입력하세요!" required>
                            <select name="searchOption" id="searchOption">
                                <option value="title">제목</option>
                                <option value="content">내용</option>
                                <option value="name">등록자</option>
                            </select>
                            <button type="submit" class="btnStyle3 white">검색</button>
                            <a href="boardWrite.php" class="btnStyle3">글쓰기</a>
                        </fieldset>
                    </form>
                </div>
            </div>
            <div class="board__table">
                <table>
                    <colgroup>
                        <col style="width: 5%;">
                        <col>
                        <col style="width: 10%;">
                        <col style="width: 15%;">
                        <col style="width: 7%;">
                    </colgroup>
                    <thead>
                        <tr>
                            <th>번호</th>
                            <th>제목</th>
                            <th>등록자</th>
                            <th>등록일</th>
                            <th>조회수</th>
                        </tr>
                    </thead>
                    <tbody>
                        <!-- <tr>
                            <td>1</td>
                            <td><a href="boardView.html">게시판 제목</a></td>
                            <td>이승연</td>
                            <td>2022-02-02</td>
                            <td>100</td>
                        </tr> -->
<?php
    if(isset($_GET['page'])){
        $page = (int) $_GET['page'];
    } else {
        $page =1;
    }

    $viewNum =20;
    $viewLimit = ($viewNum * $page) - $viewNum ;

    $sql = "SELECT b.boardID, b.boardTitle, m.youName, b.regTime, b.boardView FROM board b JOIN members m ON(b.memberID = m.memberID) ORDER BY boardID DESC LIMIT {$viewLimit}, {$viewNum}";
    $result = $connect -> query($sql);

    if($result){
        $count = $result -> num_rows;

        if($count > 0){
            for($i=0; $i<$count; $i++){
                $info = $result -> fetch_array(MYSQLI_ASSOC);

              echo "<tr>";
              echo "<td>".$info['boardID']."</td>";
              echo "<td><a href='boardView.php?boardID={$info['boardID']}'>".$info['boardTitle']."</a></td>";
              echo "<td>".$info['youName']."</td>";
              echo "<td>".date('Y-m-d', $info['regTime'])."</td>";
              echo "<td>".$info['boardView']."</td>";
              echo "</tr>";
            }
        } else {
            echo "<tr><td colspan='4'>게시글이 없습니다.</td></tr>";
        }
    }
?>
                    </tbody>
                </table>
            </div>
            <div class="board__pages">
                <ul>
<?php
    // 1~20 DESC LIMIT  0, 20 --> page1 (viewNum * 1) - viewNum
    // 21~40 DESC LIMIT 20, 20 --> page2 (viewNum * 2) - viewNum
    // 41~60 DESC LIMIT 40, 20 --> page3 (viewNum * 3) - viewNum
    // 61~80 DESC LIMIT 60, 20 --> page4 (viewNum * 4) - viewNum

    


    //총 페이지 갯수
    $boardTotalCount = ceil($boardTotalCount/20);

    //1 2 3 4 5 6 7 8 9 10 11 12 13
    $pageView =5;
    $startPage = $page - $pageView;
    $endPage = $page + $pageView;

    //처음 페이지 초기화 / 마지막 페이지 초기화
    if($startPage < 1) $startPage = 1;
    if($endPage >= $boardTotalCount) $endPage = $boardTotalCount;

    // 처음으로 / 이전
    if($page != 1 && $boardTotalCount !=0 && $page <= $boardTotalCount){
        echo "<li><a href='board.php?page=1'>처음으로</a></li>";
        $prevPage = $page -1;
        echo "<li><a href='board.php?page={$prevPage}'>이전</a></li>";
    }

    //페이지
     for($i=$startPage; $i<=$endPage; $i++){
        $active = "";
        if($i == $page) $active = "active";
        if($page <= $boardTotalCount){
            echo "<li class='{$active}'><a href='board.php?page={$i}'>{$i}</a></li>";
        }
    }

    //마지막으로 / 다음 //게시글이 없을 때
    if($page != $boardTotalCount && $page <= $boardTotalCount){
        $nextPage = $page +1;
        echo "<li><a href='board.php?page={$nextPage}'>다음</a></li>";
        echo "<li><a href='board.php?page={$boardTotalCount}'>마지막으로</a></li>";
    }
?>

                    <!-- <li><a href="#">처음으로</a></li>
                    <li><a href="#">이전</a></li>
                    <li class="active"><a href="#">1</a></li>
                    <li><a href="#">2</a></li>
                    <li><a href="#">3</a></li>
                    <li><a href="#">4</a></li>
                    <li><a href="#">5</a></li>
                    <li><a href="#">6</a></li>
                    <li><a href="#">7</a></li>
                    <li><a href="#">다음</a></li>
                    <li><a href="#">마지막으로</a></li> -->
                </ul>
            </div>
        </div>
    </main>
    <!-- //main -->

    <?php include "../include/footer.php" ?>
    <!-- // footer -->
</body>
</html>