본문 바로가기

개발과제

[노말틱 모의 해킹 취업반 9주차 개발과제 ] 게시판 만들기(5) - 각 별로 정렬되게 만들기

안녕하세요! 오늘은 날짜별, 추천수, 작성자 이름순으로 각각 정렬을 할 수 있게 선택지를 만들겠습니다!

 

 

참고로.. 오늘 만들다 보니 오류가 많이 나와서 이것저것 많이 만졌습니다! 총코드는 맨 밑에 있으니 참고해 주세요!

.

.

.

.

.

.

.

우선 리스트를 나오게 해야 되겠죠?

 

        <form method ="GET" action="board.php">
            <input type = "text" name="search" value="<?php echo mysqli_real_escape_string($conn,filter_var(strip_tags($_GET['search']),FILTER_SANITIZE_SPECIAL_CHARS));?>" placeholder="검색" >
            <input type="submit" value="검색">
            <select name="sort" onchange="this.form.submit()">
                <option value="">정렬 방식 선택</option>
                <option value="date" <?php if($_GET['sort']=='date'){echo ' selected';} ?> >날짜순</option>
                <option value="likes" <?php if($_GET['sort']=='likes'){echo ' selected';} ?> >추천순</option>
                <option value="author" <?php if($_GET['sort']=='author'){echo ' selected';} ?> >작성자순</option>
            </select>          
            <label for="date">날짜 선택:</label>
            <input type="date" id="date_value" name="date_value" value="<?php echo isset($_GET['date_value']) ? $_GET['date_value'] : ''; ?>">
        </form>

 

text란에 저렇게 적은 이유가 있습니다! 바로 저희가 검색하고 난 뒤에 검색한 문자가 text에 그대로 남게 합니다.

그리고 select에 option을 사용하여 누르면 option 구문이 나오게 했습니다!

 

 

 

그리고 this.form.submit은 onchange라는 자바스크립트를 이용하여 누르자마자 바로 GET방식으로 보내는 겁니다!

<?php if($_GET['sort']=='date'){echo ' selected';} ?> 이것은 GET부분에 sort가 date이면 selected 하게 했습니다.

 

 

 

그리고 value="<?php echo isset($_GET['date_value']) ? $_GET['date_value'] : ''; ?>" 은 만약 date_value가 있으면

그 date_value가 선택되게 있게 두는 것이고 만약 없으면 '' 빈칸으로 둡니다!

 

 

 

selected가 선택 되게 한다는 말입니다.

 

한 번 보시겠습니다.

 

좋아요!

 

검색이랑 추천순으로 해도 남아 있는 것을 알 수 있습니다.

 

여기서 보안 추가 하겠습니다! mysqli_escape 함수와 filter_var함수랑 strip_tags 함수 이용해 $_GET['sort'] 을 보호하겠습니다.

 

아 참고로 isset($_GET[]) 이럴 때도 XSS의 공격에 취약하지 않냐고 궁금해하실 수 있습니다.

다행히 이걸로 취약점이 되진 않습니다 그저 있나 없나 만 확인하거든요!

 

만약 저 GET 데이터를 처리를 할 때에 문제가 발생할 수 있습니다. sql이라던가 alert라던가요!

 

 

        <form method ="GET" action="board.php">
            <input type = "text" name="search" value="<?php echo mysqli_real_escape_string($conn,filter_var(strip_tags($_GET['search']),FILTER_SANITIZE_SPECIAL_CHARS));?>" placeholder="검색" >
            <input type="submit" value="검색">
            <select name="sort" onchange="this.form.submit()">
                <option value="">정렬 방식 선택</option>
                <option value="date" <?php if(mysqli_real_escape_string($conn, filter_var(strip_tags($_GET['sort']),FILTER_SANITIZE_SPECIAL_CHARS))=='date'){echo ' selected';} ?> >날짜순</option>
                <option value="likes" <?php if(mysqli_real_escape_string($conn, filter_var(strip_tags($_GET['sort']),FILTER_SANITIZE_SPECIAL_CHARS))=='likes'){echo ' selected';} ?> >추천순</option>
                <option value="author" <?php if(mysqli_real_escape_string($conn, filter_var(strip_tags($_GET['sort']),FILTER_SANITIZE_SPECIAL_CHARS))=='author'){echo ' selected';} ?> >작성자순</option>
            </select>          
            <label for="date">날짜 선택:</label>
            <input type="date" id="date_value" name="date_value" value="<?php echo isset($_GET['date_value']) ? $_GET['date_value'] : ''; ?>">
        </form>

 

 

좋아요.. 이러면 안심이죠

 

그다음으로 이제 GET으로 온 sort을 방금 한 것처럼 보안 함수로 씌어주고 정렬도 할 수 있게 하겠습니다!

 

이때 ORDER BY 사용하면 되겠죠?

 

변수 $start 선언한 줄 바로 아래에 코드 추가하겠습니다.

 

            //각 페이지 시작 인덱스
            $start = ($page - 1) * $num_per_page;

            if (isset($_GET['sort'])) {
                $sort = mysqli_real_escape_string($conn, filter_var(strip_tags($_GET['sort']),FILTER_SANITIZE_SPECIAL_CHARS));
                if ($sort == 'date') {
                    //날짜순
                    $sql .= " ORDER BY date_value DESC";
                } else if ($sort == 'likes') {
                    //추천순
                    $sql .= " ORDER BY like_value DESC";
                } else if ($sort == 'author') {
                    //작성자순
                    $sql .= " ORDER BY id DESC";
                }
            } 
            
            $sql .= " LIMIT $start, $num_per_page"; //최대 5개씩 호출

 

각각 이름에 맞춰서 ORDER BY의 기준점을 정해 줬습니다! 그리고 DESC을 이용해 내림차순으로 나오게 하겠습니다.

 

이러면 끝입니다!

 

한번 실행해 보겠습니다.

 

H 검색 날짜 선택해서 검색했습니다!

 

그리고 이 상태에서 정렬방식선택을 추천수로 지정해 보겠습니다.

 

쨘! 잘 나오네요!

 

좋아요! 이렇게 해서 오늘의 포스팅은 여기까지입니다! 너무 간단해서 다행이네요!

 

다음 글에는 이제 마이 페이지를 개발 하겠습니다!

 

내가 올린 글이 무엇인지 또 ID와 PW변경 기능까지! 만들어보겠습니다! 좋은 하루 되시기 전에

 

저는 따로 검색 초기화 버튼도 만들겠습니다.

 

맨 마지막에 추가하겠습니다.

 

        <form action="board.php" method="GET"> 
            <p><input type="submit" value="검색 초기화"></p>
            <input type="hidden" name="search" value="">
            <input type="hidden" name="sort" value="">
            <input type="hidden" name="date_value" value="">
        </form>

 

잘 되네요!

 

이렇게 해서 마치겠습니다 좋은 하루 보내세요!

 

 

-board.php

 

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Welcome!</title>
    </head>
    <body>
        <h1>MENU</h1>
        <?php 

            include 'DB_INFO.php'; //데이터 베이스 정보

            //데이터베이스 연결
            $conn = mysqli_connect($host,$username,$password,$db_board);

            //데이터베이스 오류시 종료
            if(mysqli_connect_errno()) {
                die("데이터 베이스 오류: ". mysqli_connect_error());
            }

            session_start(); //세션 시작

            if(!isset($_SESSION['login_id'])) {
                //로그인하지 않은 사용자
                header("Location: login.php"); //login 화면으로 바꾼다
                exit(); //이 페이지를 바로 닫는다
            }
        ?>

        <form method ="GET" action="board.php">
            <input type = "text" name="search" value="<?php echo mysqli_real_escape_string($conn,filter_var(strip_tags($_GET['search']),FILTER_SANITIZE_SPECIAL_CHARS));?>" placeholder="검색" >
            <input type="submit" value="검색">
            <select name="sort" onchange="this.form.submit()">
                <option value="">정렬 방식 선택</option>
                <option value="date" <?php if(mysqli_real_escape_string($conn, filter_var(strip_tags($_GET['sort']),FILTER_SANITIZE_SPECIAL_CHARS))=='date'){echo ' selected';} ?> >날짜순</option>
                <option value="likes" <?php if(mysqli_real_escape_string($conn, filter_var(strip_tags($_GET['sort']),FILTER_SANITIZE_SPECIAL_CHARS))=='likes'){echo ' selected';} ?> >추천순</option>
                <option value="author" <?php if(mysqli_real_escape_string($conn, filter_var(strip_tags($_GET['sort']),FILTER_SANITIZE_SPECIAL_CHARS))=='author'){echo ' selected';} ?> >작성자순</option>
            </select>          
            <label for="date">날짜 선택:</label>
            <input type="date" id="date_value" name="date_value" value="<?php echo isset($_GET['date_value']) ? $_GET['date_value'] : ''; ?>">
        </form>

        <p>
        <?php 
            //한 페이지에 보여줄 게시물 수
            $num_per_page = 5;

            //현재 페이지 번호
            if(isset($_GET['page'])) {
                $page = mysqli_real_escape_string($conn,filter_var(strip_tags(intval($_GET['page'])),FILTER_SANITIZE_SPECIAL_CHARS));
            } else {
                $page = 1;
            }
            
            //검색이 입력된 경우
            if(isset($_GET['search'])) {
                $search = mysqli_real_escape_string($conn, filter_var(strip_tags($_GET['search']),FILTER_SANITIZE_SPECIAL_CHARS));
                
                if(isset($_GET['date_value']) && strtotime($_GET['date_value'])) {
                    //날짜 선택한 경우, strtotime() 이용해 유효한 값인지 확인
                    $date_value = mysqli_real_escape_string($conn, filter_var(strip_tags($_GET['date_value']),FILTER_SANITIZE_SPECIAL_CHARS));
                    $date_value = DateTime::createFromFormat('Y-m-d', $date_value)->format('Y-m-d'); //날짜 값으로 다시 바꾼다

                    $sql = "SELECT * FROM $db_board WHERE title LIKE '%$search%' AND date_value LIKE '%$date_value%'";
                    $total_sql = "SELECT count(*) AS cnt FROM $db_board WHERE title LIKE '%$search%' AND date_value LIKE '%$date_value%'";
                }
                else {
                    //날짜가 선택이 안된 경우
                    $date_value = '';
                    $sql = "SELECT board_id,id,title,detail,views,like_value FROM $db_board WHERE title LIKE '%$search%'";
                    $total_sql = "SELECT count(*) AS cnt FROM $db_board WHERE title LIKE '%$search%'";
                }
            } else {
                //검색이 입력되지 않은 경우
                $search = '';
                $date_value = '';
                $sql = "SELECT * FROM $db_board"; //전체 게시물 검색
                $total_sql = "SELECT count(*) AS cnt FROM $db_board"; //전체 게시물 수 조회
            }
            
            $total_result = mysqli_query($conn,$total_sql); //sql문 실행
            $total_row = mysqli_fetch_assoc($total_result); //결과를 배열로 가져온다
            $total_posts = $total_row['cnt']; //배열 중 cnt의 값을 가져온다

            //전체 페이지 수
            $total_pages = ceil($total_posts / $num_per_page);

            //각 페이지 시작 인덱스
            $start = ($page - 1) * $num_per_page;
			
            //정렬해주는 조건문
            if (isset($_GET['sort'])) {
                $sort = mysqli_real_escape_string($conn, filter_var(strip_tags($_GET['sort']),FILTER_SANITIZE_SPECIAL_CHARS));
                if ($sort == 'date') {
                    //날짜순
                    $sql .= " ORDER BY date_value DESC";
                } else if ($sort == 'likes') {
                    //추천순
                    $sql .= " ORDER BY like_value DESC";
                } else if ($sort == 'author') {
                    //작성자순
                    $sql .= " ORDER BY id DESC";
                }
            } 
            
            $sql .= " LIMIT $start, $num_per_page"; //최대 5개씩 호출

            //쿼리문 실행
            $result = mysqli_query($conn, $sql);

            if(mysqli_num_rows($result) > 0) {
                //게시물 출력
                while($row = mysqli_fetch_assoc($result)) {
                    $index = $row['board_id'];
                    $id = $row['id'];
                    $title = $row['title'];
                    $like_value = $row['like_value'];
                    echo '<p><a href="view_board.php?index='.$index.'">'.$title.'</a> : '.$id.'작성함 조회수: '.$row['views'].' 좋아요 수: '.$like_value.'</p>';
                }
            } else {
                echo "게시물이 없습니다!";
            }
            
            echo '<p> [ ';
            
            // 현재 페이지를 10으로 나눈 몫에 10을 곱한 값에서 1을 빼면
            // 현재 페이지가 몇 번째 페이지 블록에 있는지 알 수 있습니다.
            $block_start = floor(($page-1)/10)*10;

            if ($block_start > 1) {
                // 이전 페이지 블록이 있다면, 다음 버튼을 출력합니다.
                $next_block_start = $block_start - 10;
                if($next_block_start == 0) {
                    $next_block_start += 1; //0페이지는 존재 하지 않기에 1더한다
                }
                echo '<a href="?page=' . $next_block_start .'"><< </a>';
            }

            // 이전 버튼 출력
            if ($page > 1) {
                echo '<a href="?page=' . ($page-1) .'">< </a> ';
            }
            
            // 페이지 링크 출력
            for ($i = $block_start+1; $i <= min($block_start+10, $total_pages); $i++) {
                if($i == $page) {
                    echo '<strong>'.$i.' </strong>';
                } else {
                    echo '<a href="?page=' . $i .'">'.$i. '</a> ';
                }
                echo ' ';
            }

            // 다음 버튼 출력
            if ($page < $total_pages) {
                echo '<a href="?page=' . ($page+1) .'">> </a> ';
            }
            
            if ($block_start+10 < $total_pages) {
                // 다음 페이지 블록이 있다면, 다음 버튼을 출력합니다.
                $next_block_start = $block_start + 11;
                echo '<a href="?page=' . $next_block_start .'">>></a>';
            }

            echo ' ]</p>';
            
        ?>
        </p>
        <p></p>
        <form action="write_board.php" method="POST"> 
            <p><input type="submit" name="write" value="게시판 작성"></p>
        </form>
        <form action="only_login.php"> 
            <p><input type="submit" value="메인페이지로"></p>
        </form>
        <form action="board.php" method="GET"> 
            <p><input type="submit" value="검색 초기화"></p>
            <input type="hidden" name="search" value="">
            <input type="hidden" name="sort" value="">
            <input type="hidden" name="date_value" value="">
        </form>
    </body>
</html>