Today I Learned …

[웹개발] 게시글 검색 기능 (기간 설정 포함) 본문

Web/APM

[웹개발] 게시글 검색 기능 (기간 설정 포함)

염베리 2021. 11. 15. 04:31

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


사담

웹개발 복기도 거의 막바지에 다다랐다.

구현은 한꺼번에 하고 기록은 사후적으로 남기려고 하니 어쩔 수 없이 귀찮은 부분도 있었지만

누적 복습에는 제법 효과적이었던 것 같다!

 

설명

오늘은 게시글 검색 기능에 대해 다뤄본다.

기간 설정 기능을 포함한다.

 

최종 화면

클릭하면 확대됩니다.


게시글 검색 기능

 

 

0. 요약

[1] board.php에 검색창을 만들어준다.

[2] 검색 과정을 실질적으로 처리하고 검색 결과를 출력할 search.php를 만들어준다.

 

 

1. 다음은 board.php에 추가할 내용이다.

<form method="get" action="search.php">
	<select name="cate" id="search_opt" onchange="info()">
            <option value=title>제목</option>
            <option value=content>내용</option>
            <option value=name>작성자</option>
	</select>
	<input class=textform type=text name=search id="search_box" autocomplete="off" placeholder="제목을 입력하세요." required>
	<input class=submit type=submit value=검색>
        <p>
            <input type=date name=date1>
            ~
            <input type=date name=date2>
        </p>
</form>

[1] 검색창을 만들어주는 과정이다.

[2] method는 get으로, action은 search.php로 넘겨준다.

 

[3] <select>와 <option> 태그를 이용해 검색 카테고리 설정을 구현한다.

⇒ 각 카테고리의 value는 GET으로 넘겨 SQL문에 꽂아줄 것이기 때문에 게시글 DB의 컬럼명을 따라준다.

[4] 검색어를 입력할 폼을 만들어준다.

[5] [검색] 버튼을 만들어준다.

[6] 기간 설정 폼을 만들어준다.

 

<script>
    function info() {
        var opt = document.getElementById("search_opt");
        var opt_val = opt.options[opt.selectedIndex].value;
        var info = ""
        if (opt_val=='title'){
        	info = "제목을 입력하세요.";
        } else if (opt_val=='content'){
        	info = "내용을 입력하세요.";
        } else if (opt_val=='name'){
        	info = "작성자를 입력하세요.";
        }
        document.getElementById("search_box").placeholder = info;
    }
</script>

[1] 위 스크립트를 <head> 태그 내부에 추가해준다.

[2] 검색 카테고리 설정에 따라 검색창에 나타나는 placeholder 값을 바꿔주는 역할을 한다.

[3] <select> 태그의 id 값과 onchange 속성 및 검색어 입력폼의 id 값을 알맞게 설정해주면 정상 작동하게 된다.

 

 

2. 다음은 검색 과정을 실질적으로 처리하고 검색 결과를 출력할 search.php의 핵심 내용이다.

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

    $cate = $_GET['cate'];
    $search = $_GET['search'];
    $date1 = $_GET['date1'];
    $date2 = $_GET['date2'];
?>

[1] GET으로 넘어온 cate를 $cate에 할당해준다.

[2] GET으로 넘어온 search를 $search에 할당해준다.

[3] GET으로 넘어온 date1을 $date1에 할당해준다.

[4] GET으로 넘어온 date2를 $date2에 할당해준다.

 

<div class=head>검색결과 | <?=$cate?> | <?=$search?></div>
    <?php
    if($date1 && $date2){ ?>
        <span class=from_to><?=$date1?> ~ <?=$date2?></span> <?php
    } ?>

[5] 사용자 편의를 위해 $cate와 $search를 화면에 출력해준다.

[6] 검색 시 기간을 설정했다면, $date1과 $date2 또한 화면에 출력해준다. 

 

<?php
    if($date1 && $date2){
        $sql_page = "SELECT * FROM board WHERE $cate LIKE '%$search%' AND written BETWEEN '$date1' AND '$date2' ORDER BY id DESC limit $start, $per";
    } else {
        $sql_page = "SELECT * FROM board WHERE $cate LIKE '%$search%' ORDER BY id DESC limit $start, $per";
    }
?>

[1] 검색 시 기간을 설정했다면, AND을 이용해 WHERE절을 조합해준다.

[2] 이 경우, 검색 결과는 $cate 컬럼에 $search를 포함하고 있으며 written이 $date1~$date2 인 레코드이다.

 

[3] 검색 시 기간을 설정하지 않았다면, $cate 컬럼에 $search를 포함하고 있는 모든 레코드를 뽑아내준다.

 

<form method="get" action="search.php">
    <select name="cate" id="search_opt" onchange="info()">
        <option value=title>제목</option>
        <option value=content>내용</option>
        <option value=name>작성자</option>
    </select>
    <input class=textform type=text name=search id="search_box" autocomplete="off" value="<?=$search?>" placeholder="검색어를 입력하세요." required>
    <input class=submit type=submit value=검색>
    <p>
        <input type=date value="<?=$date1?>" name=date1>
        ~
        <input type=date value="<?=$date2?>" name=date2>
    </p>
</form>

[1] 사용자 편의를 위해 search.php의 검색창에는 검색어와 검색 기간을 남겨준다.

[2] 아쉽게도 검색 카테고리까지 남겨주지는 못했다. 구글링해보니 매우 복잡... 일반적인 방법으로는 불가능하다.

 

 

3. 다음은 위에서 살펴본 search.php의 전체 코드이다.

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

    $cate = $_GET['cate'];
    $search = $_GET['search'];
    $date1 = $_GET['date1'];
    $date2 = $_GET['date2'];
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Search</title>
    <link href="deco.css" rel="stylesheet">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Do+Hyeon&display=swap" rel="stylesheet">
    <script>
        function info() {
            var opt = document.getElementById("search_opt");
            var opt_val = opt.options[opt.selectedIndex].value;
            var info = ""
            if (opt_val=='title'){
                info = "제목을 입력하세요.";
            } else if (opt_val=='content'){
                info = "내용을 입력하세요.";
            } else if (opt_val=='name'){
                info = "작성자를 입력하세요.";
            }
            document.getElementById("search_box").placeholder = info;
        }
    </script>
</head>
<body>
    <div class=head>검색결과 | <?=$cate?> | <?=$search?></div>
    <?php
    if($date1 && $date2){ ?>
        <span class=from_to><?=$date1?> ~ <?=$date2?></span> <?php
    } ?>
    <table style="width:1000px;" class=middle>
        <thead >
            <tr align=center>
                <th width=70>Post ID</th>
                <th width=300>제목</th>
                <th width=120>작성자</th>
                <th width=120>작성일</th>
                <th width=70>조회수</th>
                <th width=70>💜</th>
            </tr>
        </thead>
        <?php

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

            if($date1 && $date2){
                $sql = "SELECT * FROM board WHERE $cate LIKE '%$search%' AND written BETWEEN '$date1' AND '$date2'";
            } else {
                $sql = "SELECT * FROM board WHERE $cate LIKE '%$search%'";
            }
            
            $res = mysqli_query($conn, $sql);

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

            $start = ($page-1)*$per;
        
            if($date1 && $date2){
                $sql_page = "SELECT * FROM board WHERE $cate LIKE '%$search%' AND written BETWEEN '$date1' AND '$date2' ORDER BY id DESC limit $start, $per";
            } else {
                $sql_page = "SELECT * FROM board WHERE $cate LIKE '%$search%' 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 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 }

            if(!$many = mysqli_num_rows($res)){ ?>
                <tbody>
                <tr style="color:hotpink;" align=center>
                    <td>검</td>
                    <td>색</td>
                    <td>결</td>
                    <td>과</td>
                    <td>없</td>
                    <td>음</td>
                </tr>
            </tbody>
        <?php } ?>
    </table>
    <div class=bottom>
    <?php
        if($page > 1){
            echo "<a href=\"search.php?page=1&cate=$cate&search=$search&date1=$date1&date2=$date2\">[처음] </a>";
        }
        if($page > 1){
            $pre = $page - 1;
            echo "<a href=\"search.php?page=$pre&cate=$cate&search=$search&date1=$date1&date2=$date2\">이전 </a>";
        }
        $total_page = ceil($total_post / $per);
        $page_num = 1;
        while($page_num <= $total_page){
            if($page==$page_num){
                echo "<a style=\"color:hotpink;\" href=\"search.php?page=$page_num&cate=$cate&search=$search&date1=$date1&date2=$date2\">$page_num </a>";
            } else {
            echo "<a href=\"search.php?page=$page_num&cate=$cate&search=$search&date1=$date1&date2=$date2\">$page_num </a>"; }
            $page_num++;
        }
        if($page < $total_page){
            $next = $page + 1;
            echo "<a href=\"search.php?page=$next&cate=$cate&search=$search&date1=$date1&date2=$date2\">다음 </a>";
        }
        if($page < $total_page){
            echo "<a href=\"search.php?page=$total_page&cate=$cate&search=$search&date1=$date1&date2=$date2\">[끝]</a>";
        }
    ?>
    </div>
    <div class=search>
    <form method="get" action="search.php">
        <select name="cate" id="search_opt" onchange="info()">
            <option value=title>제목</option>
            <option value=content>내용</option>
            <option value=name>작성자</option>
        </select>
        <input class=textform type=text name=search id="search_box" autocomplete="off" value="<?=$search?>" placeholder="제목을 입력하세요." required>
        <input class=submit type=submit value=검색>
        <p>
        <input type=date value="<?=$date1?>" name=date1>
        ~
        <input type=date value="<?=$date2?>" name=date2>
        </p>
    </form>
    </div>
</body>
</html>

[1] CSS 및 네비바 관련 코드는 생략한다.

[2] 게시글 리스트 출력 + 페이징 기능이 구현되어있다.

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