MySQL

MYSQL PHP 게시판 사이트 검색 기능 만들기!

김도현2 2023. 5. 1. 21:03
직업에서 행복을 찾아라. 아니면 행복이 무엇인지 절대 모를 것이다.
- 엘버트 허버드
반응형

MYSQL PHP 게시판 사이트 검색 기능 만들기!

검색 기능을 추가 했습니다.

 

 

 

 

 

[ 검색 결과가 잘 나오는 모습 입니다. ]

 

 

 

 

[ 검색 결과가 없을시 나오는 화면입니다. ]

 

 

 

[ 빈 칸을 검색했을시 모습입니다. ]

 

 

 

 

 

VSCode

<?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) ";
    // $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) WHERE b.boardTitle LIKE '%{$searchKeyword}%' ORDER BY boardID DESC";
    // $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) WHERE b.boardContents LIKE '%{$searchKeyword}%' ORDER BY boardID DESC";
    // $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) WHERE m.youName LIKE '%{$searchKeyword}%' ORDER BY boardID DESC";
    
    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;
?>
<!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>게시판</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">
            <picture class="intro__images small">
                <source srcset="../assets/img/joinEnd01.png, ../assets/img/joinEnd01@2x.png 2x, ../assets/img/joinEnd01@3x.png 3x"/>
                <img src="../assets/img/joinEnd01.png" alt="회원가입 이미지">
            </picture>
            <h2>결과 게시판</h2>
            <p class="intro__text">
                웹 디자이너, 웹 퍼블리셔, 프론트앤드 개발자를 위한 게시판입니다.<br><em><?=$totalCount?></em>건의 게시물이 검색되었습니다.
            </p>
        </div>
    <!-- intro__inner -->
    <div class="board__inner">
        <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>
<?php
    $viewNum = 20;
    $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>";
        }
    }
?>
                        <!-- <tr>
                            <td>1</td>
                            <td><a href="boardView.html">게시판 제목</a></td>
                            <td>이름</td>
                            <td>2022-02-02</td>
                            <td>100</td>
                        </tr> -->
                    </tbody>
                </table>
            </div>
            <div class="board__pages">

                <ul>
<?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($boardTotalCount > 1 && $page <= $boardTotalCount){  //현재 페이지가 총 게시물 페이지를 넘어갈시 출력안됨
        if($page != 1){
            $prevPage = $page -1;
            echo "<li><a href='boardSearch.php?page=1&searchKeyword={$searchKeyword}&searchOption={$searchOption}'>처음으로</a></li>";
            echo "<li><a href='boardSearch.php?page={$prevPage}&searchKeyword={$searchKeyword}&searchOption={$searchOption}'>이전</a></li>";
        }
    }

    //페이지
    for($i=$startPage; $i<=$endPage; $i++){
        if($i>0 && $i<=$boardTotalCount && $page <= $boardTotalCount){  //현재 페이지가 총 게시물 페이지를 넘어갈시 출력안됨
            $active = "";
            if($i == $page) $active = "active";
            echo "<li class='{$active}'><a href='boardSearch.php?page={$i}&searchKeyword={$searchKeyword}&searchOption={$searchOption}'>{$i}</a></li>";
        }
    }
    
    //다음페이지, 마지막페이지
    if($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>";
    }  
?>
                    <!-- <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>
    </div>
    </main>
    <?php include "../include/footer.php" ?>
    <!-- //footer -->
</body>
</html>

 

사용자가 입력한 검색어와 검색 옵션을 받아서, MySQL 데이터베이스에서 해당 검색어를 포함하는 게시글을 찾아내는 쿼리문을 만듭니다.

그리고 그 결과를 HTML 테이블로 출력해주는 기능입니다.

 

즉 검색기능 입니다.

 

 

 

검색 PHP 

$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;

SELECT 문을 사용하여 board 테이블과 members 테이블을 JOIN하여 게시글의 제목(boardTitle), 내용(boardContents), 작성자 이름(youName), 작성일(regTime), 조회수(boardView) 등의 필드를 가져옵니다.

 

그리고 $searchOption 변수에 따라 검색 옵션에 맞게 WHERE 조건절을 추가합니다. 만약 $searchOption이 "title"이라면, boardTitle 필드에서 $searchKeyword 값을 포함하는 게시글을 검색합니다. $searchOption이 "content"이라면, boardContents 필드에서 $searchKeyword 값을 포함하는 게시글을 검색합니다.

마지막으로, $searchOption이 "name"이라면, youName 필드에서 $searchKeyword 값을 포함하는 게시글을 검색합니다.

 

마지막으로, $result 변수에 query() 메소드를 사용하여 쿼리를 실행하고, 검색된 결과의 총 개수를 $totalCount 변수에 저장합니다.

 

 

 

 

 

 

 

<?php
    $viewNum = 20;
    $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 변수에 할당합니다. 이를 통해 LIMIT 구문을 만들어 SQL 쿼리를 완성합니다.

 

SQL 쿼리 실행 결과를 $result 변수에 저장하고, 결과값이 있을 경우 $count 변수에 그 결과값의 행 수를 할당합니다. 이후, $count 변수가 0보다 크면 for 루프를 실행하여 게시글 정보를 배열 형태로 가져와서 표시합니다.

 

게시글 제목을 클릭하면 해당 게시글의 내용을 보여주는 boardView.php로 이동할 수 있도록 링크를 걸어줍니다. 게시글이 없을 경우 "게시글이 없습니다."라는 메시지를 출력합니다.

 

 

 

 

<?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($boardTotalCount > 1 && $page <= $boardTotalCount){  //현재 페이지가 총 게시물 페이지를 넘어갈시 출력안됨
        if($page != 1){
            $prevPage = $page -1;
            echo "<li><a href='boardSearch.php?page=1&searchKeyword={$searchKeyword}&searchOption={$searchOption}'>처음으로</a></li>";
            echo "<li><a href='boardSearch.php?page={$prevPage}&searchKeyword={$searchKeyword}&searchOption={$searchOption}'>이전</a></li>";
        }
    }

    //페이지
    for($i=$startPage; $i<=$endPage; $i++){
        if($i>0 && $i<=$boardTotalCount && $page <= $boardTotalCount){  //현재 페이지가 총 게시물 페이지를 넘어갈시 출력안됨
            $active = "";
            if($i == $page) $active = "active";
            echo "<li class='{$active}'><a href='boardSearch.php?page={$i}&searchKeyword={$searchKeyword}&searchOption={$searchOption}'>{$i}</a></li>";
        }
    }
    
    //다음페이지, 마지막페이지
    if($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>";
    }  
?>

검색 결과 페이지에서 페이지 번호를 출력하는 부분입니다.

 

검색 결과를 출력하는 데 필요한 페이지 수를 계산합니다. 전체 검색 결과 수를 페이지당 보여지는 게시물 수로 나누면 됩니다. ceil() 함수는 소수점 이하를 올림하여 정수값을 반환하는 함수입니다.

 

그 다음, 현재 페이지 번호를 중심으로 좌우로 몇 개의 페이지 링크를 출력할지를 정합니다. $pageView 변수를 이용해 정합니다.

 

다음으로, 시작 페이지와 끝 페이지를 계산합니다. $startPage 변수는 현재 페이지 번호를 중심으로 좌측으로 $pageView 페이지만큼 뺀 값입니다. $endPage 변수는 현재 페이지 번호를 중심으로 우측으로 $pageView 페이지만큼 더한 값입니다. 하지만 이 값이 전체 페이지 수를 넘어갈 경우에는 전체 페이지 수로 초기화합니다.

 

그 후, 이전 페이지와 처음으로 가는 페이지, 그리고 다음 페이지와 마지막 페이지로 가는 링크를 출력합니다. 현재 페이지가 첫 페이지가 아닐 때만 처음으로 가는 링크와 이전 페이지로 가는 링크가 출력됩니다. 또한, 현재 페이지가 마지막 페이지가 아닐 때만 다음 페이지로 가는 링크와 마지막 페이지로 가는 링크가 출력됩니다.

 

마지막으로, 시작 페이지부터 끝 페이지까지의 링크를 출력합니다. 현재 페이지는 활성화된 상태를 표시하기 위해 class 속성에 'active' 값을 추가합니다. 페이지 번호를 클릭하면 해당 페이지 번호를 전달하여 검색 결과를 출력합니다.