07. read.php
글 내용을 읽는 페이지입니다.
<?php include_once "_head.php";
상단에 head 파일을 불러옵니다.
// 넘어온게시글 번호 확인 $post_idx = $_GET['idx']; // 넘어온 번호가 없다면 if( empty($post_idx) ) { alert('잘못된 접근입니다.'); exit(); }
$_GET으로 넘어온 게시글 번호를 확인합니다.
게시글 번호가 넘어오지 않았다면 오류메시지를 날리고 뒤로가기 해줍니다.
exit() 명령어를 이용하여 해당 행의 아랫부분은 실행하지 않도록 해줍니다.
// 해당 게시글의 정보를 가져온다. $query = "SELECT * FROM `tbl_board_post` WHERE `post_idx` = '{$post_idx}' AND `post_status` = 'Y' LIMIT 1"; $result = $dbcon->query($query); $view = $result->fetch_array(); // 조건에 해당하는 글이 없다면 if( empty($view) ) { alert('존재하지 않는 글 또는 이미 삭제된 글입니다.'); exit; }
게시글 정보를 가져오는 부분입니다.
where 문을 통해 post_idx이 일치하는 값과 post_status=’Y’인 값을 가져오도록 합니다.
또한 결과 행이 없을경우 오류메시지를 띄우도록 합니다.
// 이전글 정보를 가져온다. $query = "SELECT * FROM `tbl_board_post` WHERE `post_idx` < '{$post_idx}' AND `post_status` = 'Y' ORDER BY `post_idx` DESC LIMIT 1"; $result = $dbcon->query($query); $prev = $result->fetch_array(); // 다음글 정보를 가져온다. $query = "SELECT * FROM `tbl_board_post` WHERE `post_idx` > '{$post_idx}' AND `post_status` = 'Y' ORDER BY `post_idx` ASC LIMIT 1"; $result = $dbcon->query($query); $next = $result->fetch_array();
이전글 정보와 다음글 정보를 가져오는 쿼리입니다.
현재 글 정렬방식이 게시글 고유 PK 내림차순 정렬 방식이기 때문에
이전글의 경우 게시글 고유 PK보다 값이 작으면서 가장 큰 값,
다음글의 경우 게시글 고유PK보다 값이 크면서 가장 작은값
을 가져오면 이전글과 다음글을 구해올수 있습니다.
단, 후에 단계형 게시판등이나 정렬순서가 다른 게시판을 만들시에는 그에맞게 정렬 조건도 변경해서 사용해야 합니다.
// 해당글이 비밀글일 경우, 비밀번호를 입력해야만 글을 볼수 있다. if( $view['post_is_secret'] == 'Y' ) { // 세션을 통해 비밀번호 입력여부를 알아온다. if( ! $_SESSION['post_check_'.$post_idx] ) { // 현재 URL을 구해온다. $reurl = urlencode(current_url()); // 패스워드 입력후 다시 돌아올 URL header('Location: password.php?idx='.$post_idx.'&reurl='.$reurl, TRUE); // 패스워드 입력폼으로 이동 } }
해당글이 비밀글인 경우에는 비밀번호를 입력하도록 합니다.
세션을 체크하여 현재 게시글에 대한 세션이 있는지 확인하고
없다면 비밀번호 확인페이지로 이동하도록 합니다.
게시글 PK 와 현재 페이지 주소를 GET 으로 같이 넘겨주면서 이동시키도록 합시다.
// 조회수를 증가한다. // 한사람이 여러번 조회수를 올리는걸 막기위해서 세션을 이용 if( ! $_SESSION['post_hit_'.$post_idx] ) { // 조회수 증가 처리 (DB) $query = "UPDATE `tbl_board_post` SET `post_hit` = `post_hit` + 1 WHERE `post_idx` = '{$post_idx}'"; $dbcon->query($query); // 세션에 저장해서 이후에 조회수가 올라가는걸 방지 $_SESSION['post_hit_'.$post_idx] = time(); // 이미 불러온 데이타에도 증가한 조회수를 처리해준다. $view['post_hit']++; }
조회수를 증가를 처리하는 부분입니다.
한사람이 여러번 조회수를 올리는걸 막기위해 조회수 증가 처리가 완료되면 세션에 저장하도록 합니다.
// 이 게시글의 댓글 목록을 가져온다. $query = "SELECT * FROM `tbl_board_comment` WHERE `post_idx` = '{$post_idx}' ORDER BY `cmt_idx` ASC"; $comment_result = $dbcon->query($query);
이 게시글에 달린 댓글목록을 가져오도록 합니다.
<style> .post-info { margin:0; padding:0; list-style:none; font-size:0px;} .post-info > li { display:inline-block; font-size:12px; color:#797979;} .post-info > li + li:before { content:''; display:inline-block; width:1px; height:8px; background:#ddd; margin:0px 5px;} </style> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"><?=$view['post_title']?></h4> </div> <div class="panel-body"> <ul class="post-info"> <li><?=$view['mem_nickname']?></li> <li><?=$view['post_regtime']?></li> <li><?=$view['post_hit']?></li> </ul> </div> <div class="panel-body"> <?=$view['post_content']?> </div> <div class="panel-footer"> <div class="pull-left"> <?php if($prev) : ?> <a href="<?=BASEURL?>/read.php?idx=<?=$prev['post_idx']?>" class="btn btn-sm btn-default"><i class="fa fa-caret-left"></i> 이전글</a> <?php endif;?> <a href="<?=BASEURL?>/index.php" class="btn btn-sm btn-default">목록</a> <?php if($next) : ?> <a href="<?=BASEURL?>/read.php?idx=<?=$next['post_idx']?>" class="btn btn-sm btn-default"><i class="fa fa-caret-right"></i> 다음글</a> <?php endif;?> </div> <div class="pull-right"> <a class="btn btn-sm btn-info" href="<?=BASEURL?>/write.php?idx=<?=$view['post_idx']?>"><i class="fa fa-pencil"></i> 수정</a> <a class="btn btn-sm btn-danger" onclick="return confirm('이 글을 삭제하시겠습니까?');" href="<?=BASEURL?>/delete.php?idx=<?=$view['post_idx']?>"><i class="fa fa-trash"></i> 삭제</a> </div> <div class="clearfix"></div> </div> </div>
글 내용보기 부분의 뷰코드입니다.
단순히 내용부분을 출력해주면 됩니다.
[이전글] 과 [다음글] 존재여부에 따라 이전글, 다음글 버튼을 만들어줍니다.
<style> .widget-area { -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px;background: none repeat scroll 0 0 rgba(0, 0, 0, 0); -webkit-box-shadow: none; -moz-box-shadow: none; -ms-box-shadow: none; -o-box-shadow: none; box-shadow: none; float: left; margin-top: 30px; padding: 0px; position: relative; width: 100%; } .status-upload { background: none repeat scroll 0 0 #f5f5f5; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; float: left; width: 100%;} .status-upload form { float: left; width: 100%; } .status-upload form textarea { background: none repeat scroll 0 0 #fff; border: medium none; -webkit-border-radius: 4px 4px 0 0; -moz-border-radius: 4px 4px 0 0; -ms-border-radius: 4px 4px 0 0; -o-border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0; color: #777777; float: left; font-family: Lato; font-size: 14px; height: 142px; letter-spacing: 0.3px; padding: 20px; width: 100%; resize:vertical; outline:none; border: 1px solid #F2F2F2; resize:none;} .status-upload form button { border: medium none; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; color: #fff; float: right; font-size: 12px; letter-spacing: 0.3px; margin:9px; padding: 6px 15px;} .status-upload form button > i { margin-right: 7px; } .comments-list { padding: 0; margin-top: 20px; list-style-type: none;} .comments-list .comment { display: block; width: 100%; margin: 20px 0;} .comments-list .comment .avatar { width: 35px; height: 35px;} .comments-list .comment .comment-heading { display: block; width: 100%;} .comments-list .comment .comment-heading .user { font-size: 14px; font-weight: bold; display: inline; margin-top: 0; margin-right: 10px;} .comments-list .comment .comment-heading .time { font-size: 12px; color: #aaa; margin-top: 0; display: inline;} .comments-list .comment .comment-body { margin-left: 50px; } .comments-list .comment > .comments-list { margin-left: 50px; } </style> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title">댓글</h4> </div> <div class="panel-body"> <!--START:댓글 입력창--> <div class="widget-area"> <div class="status-upload"> <form method="post" action="<?=BASEURL?>/comment_ok.php" class="form-inline"> <input type="hidden" name="post_idx" value="<?=$view['post_idx']?>"> <textarea name="cmt_content" placeholder="댓글 내용을 입력하세요" required></textarea> <div style="margin-top:9px;float:left;margin-left:15px;"> <label>관리자 비밀번호</label> <input type="password" class="form-control input-sm" name="admin_password" required> </div> <button type="submit" class="btn btn-success green"><i class="fa fa-share"></i>댓글입력</button> <div class="clearfix"></div> </form> </div> </div> <div class="clearfix"></div> <!--END:댓글입력창--> <!--START:댓글 목록--> <ul class="comments-list" style="margin-top:20px;border-top:1px solid #ddd;"> <?php while($comment = $comment_result->fetch_array() ) :?> <li class="comment" id="comment_<?=$comment['cmt_idx']?>"> <a class="pull-left" href="#"> <img class="avatar" src="http://bootdey.com/img/Content/user_1.jpg" alt="avatar"> </a> <div class="comment-body"> <div class="comment-heading"> <h4 class="user">관리자</h4> <h5 class="time"><?=sns_datetime($comment['cmt_regtime'])?></h5> </div> <p><?=nl2br($comment['cmt_content'])?></p> </div> </li> <?php endwhile?> </ul> <!--END:댓글 목록--> </div> </div>
댓글부분의 뷰코드입니다.
댓글입력창 + 댓글 목록으로 구성되어 있으며,
댓글은 관리자만 입력가능하기 때문에 관리자 비밀번호를 입력받도록 설정하였습니다.
완성코드
<?php include_once "_head.php"; // 넘어온게시글 번호 확인 $post_idx = $_GET['idx']; // 넘어온 번호가 없다면 if( empty($post_idx) ) { alert('잘못된 접근입니다.'); exit(); } // 해당 게시글의 정보를 가져온다. $query = "SELECT * FROM `tbl_board_post` WHERE `post_idx` = '{$post_idx}' AND `post_status` = 'Y' LIMIT 1"; $result = $dbcon->query($query); $view = $result->fetch_array(); // 조건에 해당하는 글이 없다면 if( empty($view) ) { alert('존재하지 않는 글 또는 이미 삭제된 글입니다.'); exit; } // 이전글 정보를 가져온다. $query = "SELECT * FROM `tbl_board_post` WHERE `post_idx` < '{$post_idx}' AND `post_status` = 'Y' ORDER BY `post_idx` DESC LIMIT 1"; $result = $dbcon->query($query); $prev = $result->fetch_array(); // 다음글 정보를 가져온다. $query = "SELECT * FROM `tbl_board_post` WHERE `post_idx` > '{$post_idx}' AND `post_status` = 'Y' ORDER BY `post_idx` ASC LIMIT 1"; $result = $dbcon->query($query); $next = $result->fetch_array(); // 해당글이 비밀글일 경우, 비밀번호를 입력해야만 글을 볼수 있다. if( $view['post_is_secret'] == 'Y' ) { // 세션을 통해 비밀번호 입력여부를 알아온다. if( ! $_SESSION['post_check_'.$post_idx] ) { // 현재 URL을 구해온다. $reurl = urlencode(current_url()); // 패스워드 입력후 다시 돌아올 URL header('Location: password.php?idx='.$post_idx.'&reurl='.$reurl, TRUE); // 패스워드 입력폼으로 이동 } } // 조회수를 증가한다. // 한사람이 여러번 조회수를 올리는걸 막기위해서 세션을 이용 if( ! $_SESSION['post_hit_'.$post_idx] ) { // 조회수 증가 처리 (DB) $query = "UPDATE `tbl_board_post` SET `post_hit` = `post_hit` + 1 WHERE `post_idx` = '{$post_idx}'"; $dbcon->query($query); // 세션에 저장해서 이후에 조회수가 올라가는걸 방지 $_SESSION['post_hit_'.$post_idx] = time(); // 이미 불러온 데이타에도 증가한 조회수를 처리해준다. $view['post_hit']++; } // 이 게시글의 댓글 목록을 가져온다. $query = "SELECT * FROM `tbl_board_comment` WHERE `post_idx` = '{$post_idx}' ORDER BY `cmt_idx` ASC"; $comment_result = $dbcon->query($query); ?> <style> .post-info { margin:0; padding:0; list-style:none; font-size:0px;} .post-info > li { display:inline-block; font-size:12px; color:#797979;} .post-info > li + li:before { content:''; display:inline-block; width:1px; height:8px; background:#ddd; margin:0px 5px;} </style> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"><?=$view['post_title']?></h4> </div> <div class="panel-body"> <ul class="post-info"> <li><?=$view['mem_nickname']?></li> <li><?=$view['post_regtime']?></li> <li><?=$view['post_hit']?></li> </ul> </div> <div class="panel-body"> <?=$view['post_content']?> </div> <div class="panel-footer"> <div class="pull-left"> <?php if($prev) : ?> <a href="<?=BASEURL?>/read.php?idx=<?=$prev['post_idx']?>" class="btn btn-sm btn-default"><i class="fa fa-caret-left"></i> 이전글</a> <?php endif;?> <a href="<?=BASEURL?>/index.php" class="btn btn-sm btn-default">목록</a> <?php if($next) : ?> <a href="<?=BASEURL?>/read.php?idx=<?=$next['post_idx']?>" class="btn btn-sm btn-default"><i class="fa fa-caret-right"></i> 다음글</a> <?php endif;?> </div> <div class="pull-right"> <a class="btn btn-sm btn-info" href="<?=BASEURL?>/write.php?idx=<?=$view['post_idx']?>"><i class="fa fa-pencil"></i> 수정</a> <a class="btn btn-sm btn-danger" onclick="return confirm('이 글을 삭제하시겠습니까?');" href="<?=BASEURL?>/delete.php?idx=<?=$view['post_idx']?>"><i class="fa fa-trash"></i> 삭제</a> </div> <div class="clearfix"></div> </div> </div> <style> .widget-area { -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px;background: none repeat scroll 0 0 rgba(0, 0, 0, 0); -webkit-box-shadow: none; -moz-box-shadow: none; -ms-box-shadow: none; -o-box-shadow: none; box-shadow: none; float: left; margin-top: 30px; padding: 0px; position: relative; width: 100%; } .status-upload { background: none repeat scroll 0 0 #f5f5f5; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; float: left; width: 100%;} .status-upload form { float: left; width: 100%; } .status-upload form textarea { background: none repeat scroll 0 0 #fff; border: medium none; -webkit-border-radius: 4px 4px 0 0; -moz-border-radius: 4px 4px 0 0; -ms-border-radius: 4px 4px 0 0; -o-border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0; color: #777777; float: left; font-family: Lato; font-size: 14px; height: 142px; letter-spacing: 0.3px; padding: 20px; width: 100%; resize:vertical; outline:none; border: 1px solid #F2F2F2; resize:none;} .status-upload form button { border: medium none; -webkit-border-radius: 4px; -moz-border-radius: 4px; -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; color: #fff; float: right; font-size: 12px; letter-spacing: 0.3px; margin:9px; padding: 6px 15px;} .status-upload form button > i { margin-right: 7px; } .comments-list { padding: 0; margin-top: 20px; list-style-type: none;} .comments-list .comment { display: block; width: 100%; margin: 20px 0;} .comments-list .comment .avatar { width: 35px; height: 35px;} .comments-list .comment .comment-heading { display: block; width: 100%;} .comments-list .comment .comment-heading .user { font-size: 14px; font-weight: bold; display: inline; margin-top: 0; margin-right: 10px;} .comments-list .comment .comment-heading .time { font-size: 12px; color: #aaa; margin-top: 0; display: inline;} .comments-list .comment .comment-body { margin-left: 50px; } .comments-list .comment > .comments-list { margin-left: 50px; } </style> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title">댓글</h4> </div> <div class="panel-body"> <!--START:댓글 입력창--> <div class="widget-area"> <div class="status-upload"> <form method="post" action="<?=BASEURL?>/comment_ok.php" class="form-inline"> <input type="hidden" name="post_idx" value="<?=$view['post_idx']?>"> <textarea name="cmt_content" placeholder="댓글 내용을 입력하세요" required></textarea> <div style="margin-top:9px;float:left;margin-left:15px;"> <label>관리자 비밀번호</label> <input type="password" class="form-control input-sm" name="admin_password" required> </div> <button type="submit" class="btn btn-success green"><i class="fa fa-share"></i>댓글입력</button> <div class="clearfix"></div> </form> </div> </div> <div class="clearfix"></div> <!--END:댓글입력창--> <!--START:댓글 목록--> <ul class="comments-list" style="margin-top:20px;border-top:1px solid #ddd;"> <?php while($comment = $comment_result->fetch_array() ) :?> <li class="comment" id="comment_<?=$comment['cmt_idx']?>"> <a class="pull-left" href="#"> <img class="avatar" src="http://bootdey.com/img/Content/user_1.jpg" alt="avatar"> </a> <div class="comment-body"> <div class="comment-heading"> <h4 class="user">관리자</h4> <h5 class="time"><?=sns_datetime($comment['cmt_regtime'])?></h5> </div> <p><?=nl2br($comment['cmt_content'])?></p> </div> </li> <?php endwhile?> </ul> <!--END:댓글 목록--> </div> </div>
[catlist id=76 numberposts=14 conditional_title=”PHP 질문과 답변 게시판 만들기” orderby=date]