요기보드3   필수기초 선택과목 요기보드 그누보드 로그인

요기보드 Ver.3


bbs_comment.php

댓글을 보여주고 또 댓글 추가창을 관리하는 코드들이 들어 있는 파일이야.
우선 전체적인 흐름 부터 봐야겠지?


... 게시글에서 댓글 갯수 파악해서 $cnt 에 저장..
    if ($cnt > 0) {  // 댓글이 있으면..
        while ($row = mysqli_fetch_array($result)) { // 가져올 댓글 하나씩 가져와서..
            댓글 내용 보여주기 
            관리자와 댓글 쓴 회원은 [수정][삭제]버튼 표시
            댓글에 첨부 그림파일 있으면 보여주기
            댓글 내용의 Html 태그는 관리자급 만 작동하게
        }
    }
    if (!isset($_SESSION['ssuno']) OR $_SESSION['sslevel'] < $write_level) { 
        return; // 로그인 안했거나 글쓰기 등급이 안되면 아래쪽 안가고 여기서 나간다.
    }; 
    echo '<div class="w3-center w3-margin-bottom">'
        댓글 추가에 그림파일 첨부했으면 그림을 보여주기 
    echo '</div>';
    
<form method="post" . . .>
    댓글추가창 
</form>
<script ...>
    댓글에 그림선택했을때 그림을 보여주는 스크립트 코드 
</script>

이제 대충 코드에 적은 주석 내용을 봐도 흐름이 이해 되지?
새로 나온 함수나 기술에 대해서만 이야기해 볼께..

▶ JOIN 을 이용한 쿼리명령

$query = "SELECT B.`bno`, B.`datetime`, B.`linkfile`, B.`content`, B.`uno`, B.`writer`, U.`level`
            FROM yg_bbs as B
            LEFT JOIN yg_user as U on B.uno = U.uno
            WHERE B.parent=$bno";

처음 보는 쿼리 명령이 나왔어.
이것은 yg_bbs 테이블과 yg_user 테이블 두개를 연결해서 원하는 필드 값을 찾기 위해 JOIN 이라는 지시어(?)를 사용한 쿼리야.
쿼리문 내용은 yg_bbs 에서 "parent 필드의 값이 원래 게시글 번호인 $bno 와 같은 자료들만 찾아라." 는 명령이야.
parent 에 저장된 값이 원래 게시글 번호인 $bno 와 같은 자료가 곳 원게시글($bno)에 대한 댓글들이야.
그러니 이것들만 가져오면 원게시글에 대한 댓글들인거지.
그런데 SELECT 라인 맨 뒤에 U.`level' 이 보이네?

댓글을 보여 주면서 우리는 각 댓글 작성한 회원의 등급도 알아야 할 필요가 생겼어.
그래서 회원등급(level)이 관리자급이면 댓글 내용에 태그가 있으면 제대로 작동하게 하고, 일반회원이면 출력하기 전에 보안을 위해 htmlspecialchars()로 태그를 html 엔터티 대체문자로 바꿔서 출력시키려고 해.
왜냐하면 누구인지 모르는 일반회원이 댓글에 악의적인 스크립트나 태그를 넣어서 악의적인 해킹을 시도할 수도 있잖아. 그걸 막아 보려는 거지.
반면 관리자급 등급이면 어떤 태그나 스크립트도 마음대로 쓰고 또 작동하게 하려고 해.

그런데 yg_bbs 테이블에는 회원번호(uno)는 있는데 등급(level)이 없어.
회원등급(level)은 회원정보를 저장한 yg_user 테이블에 있거든.
그래서 yg_bbs 테이블에서 댓글을 가져오면서 yg_bbs의 uno 에 해당하는 자료를 yg_user 에서 찾아서 거기에 있는 level 도 함께 가져와라... 뭐 이런 뜻이야.
어쩐지 쿼리문에 JOIN 이니 하는게 그런거 같지 않아?
여기서 JOIN 까지 설명하지는 않을께. 구글이나 W3Schools 의 MySQL 에서 검색해 보면 다양한 JOIN 명령들에 대해 배울 수 있어.

뭐 어쨌든 간에 이렇게 해서 아래 줄 mysqli_query($dbc, $query)을 실행하면 $result 에 게시글 정보와 함께 level 에 대한 정보까지 받아 올 수 있어.
그래서 이 정보를 기반으로 이 level 은 아래 코드에서 사용하게 돼.


// 댓글 내용의 html 태그는 관리자급만 작동하게..
if ($row['level'] < ADMIN_LEVEL) {
	echo nl2br(htmlspecialchars($row['content']));
} else {
	echo nl2br($row['content']);
}

자, 보면 $row['level'] 이 댓글을 쓴 사람의 회원등급이야.
이 등급이 환경설정에서 설정한 관리자등급인 ADMIN_LEVEL 보다 작으면 일반 회원인거지.
그렇다면 이 경우에는 본문 내용인 $row['content'] 를 출력하기 전에 htmlspecialchars() 로 한 번 감싸서 태그가 작동하지 않도록 했어.
그리고 관리자가 작성한 댓글은 태그나 스크립트 까지 다 작동하게 아무런 조치를 하지 않고 줄바꿈 처리만 해서 출력했어.
이 두가지 차이점은 여러분이 직접 관리자와 일반회원으로 각각 로그인한 뒤 <h1> 같은 태그를 넣어서 댓글을 추가해 보면 차이점을 바로 알 수 있을거야.

그런데 여기서 그렇다면 댓글이 아닌 원 게시글은 어떻게 했지?.. 아는 사람 있어?
원게시글을 저장하고 볼 때는 댓글과 다르게 했어.
원게시글은 작성해서 yg_bbs 테이블에 저장할 때 일반회원, 관리자에 따라 다르게 저장되도록 했어.
(한번 bbs.php 의 function save_bbs() 부분을 잘 살펴봐.)
즉 원글은 저장할 때 일반회원의 글 본문을 htmlspecialchars() 로 감싸서 저장했고, 댓글은 저장할 때는 사용자가 입력한 내용을 태그 포함해 그대로 저장하고 대신 꺼내 와서 볼 때 htmlspecialchars() 로 감싸서 보여 주었어.

요기보드에서 이렇게 원글, 댓글 두 개가 다르게 한 이유가 뭘까?
특별히 딴 이유는 없어. 여러분 공부하라고...ㅎ
그러나 여러분이 만드려는 웹사이트의 성격에 따라 둘 중 하나를 선택해야 할 경우도 있을 수 있어.
어떤 경우에는 저장내용이 태그 그대로 저장되어야 다른 프로그램에서 꺼내 쓸 때 제대로 작동하는 경우도 있을거 아냐.
이건 여러분의 웹사이트의 내용에 따라 결정해야 할 문제이기도 해.
일단 요기보드에서는 일반회원이 쓴 글을 DB에 저장할 때 원글은 htmlspecialchars() 를 거쳐서 html 엔티티 문자로 변경해 저장하고, 댓글은 그대로 저장한다는 점 만 알고 있어.

▶ enctype="multipart/form-data"
이건 HTML 이 담당하는 기능인데 그림파일을 함께 보내려면 form 태그에 꼭 enctype="multipart/form-data" 로 지정해 주어야 해.
인터넷에서 검색하면 자세하게 알 수 있어.

▶ <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo BBS_IMG_MAX; ?>" />
그림파일을 첨부할 때 최대크게 제한을 지정하는 코드야.
여기서 지정한 크기 보다 더 큰 파일은 서버로 전송이 안되고 에러가 발생할거야.
최대 크기는 _config.php 파일안에서 상수 BBS_IMG_MAX 의 값으로 들어가니 최대 크기를 늘리고 싶으면 _config.php 에서 값을 조정하면 되겠지?
참고로 요즘 스마트폰으로 찍은 고해상도 사진을 첨부파일로 그대로 허용하면 월 500 원 짜리 여러분의 서버는 불과 몇 장 올리지도 못하고 하드 공간 꽉 차버리고 말거야...

▶ <input type="hidden" name="subject" value="<?php echo $subject; ?>" />
화면상의 댓글 입력창에는 보이지 않지만 [댓글저장] 버튼을 눌러서 서버로 보낼 때 제목도 함께 보내기 위해 <input>태그에 type="hidden" 형식으로 지정하고 내용은 현재 원글의 제목을 보내고 있어.

맨 아래쪽에 있는 <script>~</script>는 댓글에서 선택한 첨부 그림파일을 서버에 올리기 전에 미리 보여주는 코드로 이미 bbs_edit.php 에서 간단하게 설명했어.
그것과 거의 동일한 코드야.


목차제 목조회
579
338
277
256
269
246
203
198
160
168
214
223
233
117
148
160
151
186