ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [PHP] 게시판 만들기 - 댓글 기능 구현 ② (ajax 활용)
    프로그래밍/PHP 2020. 7. 19. 18:19

    저번 실습에서는 LiveRe에서 제공하는 댓글 서비스를 이용하여 댓글 기능을 기존의 프로젝트에 추가해봤습니다.

    이번시간에는 직접 첫 실습에서 설계한 DB를 기반으로 ajax 통신을 이용해 다음과 같이 댓글 기능을 구현해보도록 하겠습니다.

     

    ajax를 이용한 실시간 댓글 기능

    실습은 다음과 같은 순서로 진행됩니다.

    1. 댓글 목록 페이지 디자인을 위한 reply.css

    2. 댓글 목록 페이지 및 기능 구현, 모달창 구현 read.php

    3. 댓글 기능 이벤트 구현(ajax) reply.js

    4. 댓글 작성 기능 구현 reply_ok.php

    5. 댓글 삭제 기능 구현 reply_delete.php

     

     

    1. 댓글 목록 페이지 디자인

    /* 댓글 css */
    .reply_view {
    	width:900px;
    	margin-top:100px; 
    	word-break:break-all;
    }
    .dat_view {
    	font-size: 14px;
    	padding:10px 0 15px 0;
    	border-bottom: solid 1px gray;
    }
    .dat_ins {
    	margin-top:50px;
    }
    .dat_edit_t{
    	width:520px;
    	height:70px;
    	position: absolute;
    	top: 40px;
    }
    .rep_con {
    	width:700px;
    	height: 56px; 
    }
    .rep_btn {
    	position: absolute;
    	width:100px;
    	height:56px;
    	font-size:16px;
    	margin-left: 10px; 
    }

    해당 코드를 진행중인 프로젝트의 css 폴더에 새로운 파일을 하나 만들어 작성해줍니다.

     

    2. 댓글 목록 페이지 및 기능

    read.php에 위에서 작성한 css 파일을 적용시키기 위해 다음과 같이 설정을 해주고

    <link rel="stylesheet" href="css/reply.css"> 

     

    저번 LiveRe를 이용해서 댓글 기능을 구현했을 때와 마찬가지로 수정, 삭제 버튼 아래에 댓글 목록을 가져오기 위해 다음과 같이 코드를 추가해줍니다.

    <!-- 댓글 불러오기 -->
    		<div class="container">
    			<div class="reply_view">
    				<h3 style="padding:10px 0 15px 0; border-bottom: solid 1px gray;">댓글목록</h3>
    				<?php 
    					$sql3=mq("select
    						*
    					  from
    						reply
    					  where
    						con_num='".$bno."'
    					  order by
    						idx desc
    					");
    					while($reply=$sql3->fetch_array()){
    				?>
    				<div class="dat_view">
    					<div><b><?=$reply['name']?></b></div>
    					<div class="dap_to comt_edit"><?php echo nl2br("$reply[content]"); ?></div>
    					<div class="rep_me dap_to"><?=$reply['date']?></div>
    					<div class="rep_me rep_menu">
    						<a class="dat_del_btn" href="#">삭제</a>
    					</div>
    				</div>
                    		<?php } ?>
    			</div>
    		</div>
    		<!-- 댓글 불러오기 끝 -->

    댓글을 불러오는 로직은 게시물 목록을 가져왔을 때의 로직과 동일합니다. 이전 실습을 잘 따라오셨다면 어렵지 않게 이해가 가능할 것이라고 생각해 자세한 설명은 생략하고 reply 테이블의 컬럼들이 각각 어떤 의미를 가지는지에 대한 정보만 다시 링크로 남겨두도록 하겠습니다.

     

    이번에는 댓글 작성 폼을 만들어보도록 하겠습니다.

    	<!-- 댓글 달기 -->
        <div class="dat_ins">
          <input type="hidden" name="bno" class="bno" value=<?=$bno?>>
          <input type="hidden" name="dat_user" id="dat_user" class="dat_user" value=<?=$userid?>>
          <input type="password" name="dat_pw" id="dat_pw" class="dat_pw" size="15" placeholder="비밀번호">
          <div style="margin-top:10px;">
            <textarea name="content" class="rep_con" id="rep_con"></textarea>
            <button id="rep_btn" class="rep_btn">댓글</button>
          </div>
        </div>

    댓글 작성 폼의 input 값들을 hidden 속성으로 설정하여 앞단에서 보여지지 않게 설정한 후 이 정보들을 ajax 통신을 이용하여 댓글 작성 기능 로직을 처리하는 reply_ok.php 로 보낼 예정입니다.

     

    ※ input 태그의 value에 해당하는 값들이 ajax 통신을 통해 보내집니다. 위의 코드를 보면 현재 세션의 아이디를 값으로 넘기는 것을 볼 수 있는데, 이는 댓글을 작성한 아이디가 누구였는지를 표시하기 위함입니다.

     

    다음으로 각각의 댓글 목록에서 삭제 버튼을 눌렀을 때 나오는 모달창을 구현해보도록 하겠습니다.

    <!-- 댓글 삭제 모달창 구현 -->
    <div class="modal fade" id="rep_modal_del">
      <div class="modal-dialog">
        <div class="modal-content">
          <!-- header -->
          <div class="modal-header">
            <!-- 닫기(x) 버튼 -->
            <button type="button" class="close" data-dismiss="modal">×</button>
            <!-- header title -->
            <h4 class="modal-title"><b>댓글 삭제</b></h4>
          </div>
          <!-- body -->
            <div class="modal-body">
              <form method="post" id="modal_form" action="reply_delete.php">
              <input type="hidden" name="rno" value="<?=$reply['idx'];?>" /><input type="hidden" name="b_no" value="<?=$bno;?>">		
              <p>비밀번호  <input type="password" name="pw" /> <input type="submit" class="btn btn-primary" value="확인" /></p>
            </form>
          </div>
        </div>
      </div>
    </div>
    <!-- 댓글 삭제 모달창 구현 끝 -->

    해당 모달창은 비밀글을 구현하는 실습에서 해봤던 것과 동일합니다. hidden 값으로 댓글의 idx 값, 게시판의 idx 값을 그리고 DB에 저장된 패스워드와 비교하기 위해 패스워드를 입력받아 post 방식으로 reply_delete.php로 데이터를 전송합니다. (자세한 내용은 다음 링크를 참고합니다.)

     

    다음은 read.php에서 수정한 내용을 전부 결합한 코드입니다.

    <!-- 댓글 불러오기 -->
    		<div class="container">
    			<div class="reply_view">
    				<h3 style="padding:10px 0 15px 0; border-bottom: solid 1px gray;">댓글목록</h3>
    				<?php 
    					$sql3=mq("select
    						*
    					  from
    						reply
    					  where
    						con_num='".$bno."'
    					  order by
    						idx desc
    					");
    					while($reply=$sql3->fetch_array()){
    				?>
    				<div class="dat_view">
    					<div><b><?=$reply['name']?></b></div>
    					<div class="dap_to comt_edit"><?php echo nl2br("$reply[content]"); ?></div>
    					<div class="rep_me dap_to"><?=$reply['date']?></div>
    					<div class="rep_me rep_menu">
    						<a class="dat_del_btn" href="#">삭제</a>
    					</div>
    				</div>
    				<!-- 댓글 삭제 모달창 구현 -->
    				<div class="modal fade" id="rep_modal_del">
    					<div class="modal-dialog">
    						<div class="modal-content">
    							<!-- header -->
    							<div class="modal-header">
    								<!-- 닫기(x) 버튼 -->
    								<button type="button" class="close" data-dismiss="modal">×</button>
    								<!-- header title -->
    								<h4 class="modal-title"><b>댓글 삭제</b></h4>
    							</div>
    							<!-- body -->
    							<div class="modal-body">
    								<form method="post" id="modal_form" action="reply_delete.php">
    									<input type="hidden" name="rno" value="<?=$reply['idx'];?>" /><input type="hidden" name="b_no" value="<?=$bno;?>">		
    									<p>비밀번호  <input type="password" name="pw" /> <input type="submit" class="btn btn-primary" value="확인" /></p>
    								</form>
    							</div>
    					  	</div>
    				  	</div>
    				</div>
    				<!-- 댓글 삭제 모달창 구현 끝 -->
    			
    				<?php } ?>
    				<!-- 댓글 달기 -->
    				<div class="dat_ins">
    					<input type="hidden" name="bno" class="bno" value=<?=$bno?>>
    					<input type="hidden" name="dat_user" id="dat_user" class="dat_user" value=<?=$userid?>>
    					<input type="password" name="dat_pw" id="dat_pw" class="dat_pw" size="15" placeholder="비밀번호">
    					<div style="margin-top:10px;">
    						<textarea name="content" class="rep_con" id="rep_con"></textarea>
    						<button id="rep_btn" class="rep_btn">댓글</button>
    					</div>
    				</div>
    			</div>
    		</div>
    <!-- 댓글 불러오기 끝 -->

     

    3. 댓글 기능 이벤트(ajax)

    read.php 에 다음과 같이 자바스크립트 파일을 참조하게끔 설정하고

    <script src="./js/reply.js"></script>

     

    진행중인 프로젝트의 js 폴더에 다음과 같이 reply.js를 만들어줍니다. 

    /* 댓글 작성 이벤트(ajax) */
    $(function(){
    	$("#rep_btn").click(function(){
    		$.ajax({				//비동기통신방법, 객체로 보낼때{}사용
    			url : "reply_ok.php",
    			type : "post",
    			data : {
    				"bno" : $(".bno").val(),
    				"dat_user" : $(".dat_user").val(),
    				"dat_pw" : $(".dat_pw").val(),
    				"rep_con" : $(".rep_con").val(),
    			},
    			success : function(data){
    				alert("댓글이 작성되었습니다");
    				location.reload();
    			}
    		});
    	});
    
    
    	/* 댓글 삭제 이벤트 */
    	$(".dat_del_btn").click(function(){
    		$("#rep_modal_del").modal();
    	});
    	
    		
    });

    '#rep_btn' 은 read.php의 댓글 작성 폼에서 댓글을 달기 위한 버튼의 id 이름을 의미합니다. 댓글 작성 폼에서 댓글 버튼을 누르면 위와 같이 JSON 형식으로 reply_ok.php에 데이터를 전송합니다. 작업이 성공하면 댓글이 작성되었다는 alert창이 뜨고 location.reload() 함수를 통해 자동으로 새로고침 처리가 됩니다.

     

    새로고침을 하는 이유는 댓글 작성이 완료되고 난 후 새로고침을 눌러야만 삭제 버튼을 눌렀을 때 이벤트가 발생하는 오류가 존재해서 이와 같이 처리를 해주었습니다.

     

    '.dat_del_btn'은 댓글 목록에 있는 삭제 버튼의 class 이름을 의미합니다. 해당 삭제 버튼을 누르면 모달창 이벤트가 나타납니다. 

     

    4. 댓글 작성 기능

    <?php
    	include './config.php';
    	include './db/db_con.php';
    	
    	$bno = $_POST['bno'];
    	$userpw = password_hash($_POST['dat_pw'], PASSWORD_DEFAULT);
    	$sql = mq("insert
    					reply
    			   set
    					con_num = '".$bno."',
    					name = '".$_POST['dat_user']."',
    					pw = '".$userpw."',
    					content = '".$_POST['rep_con']."'
    			");
    ?>
    	
    

    ajax 통신을 통해 전달된 데이터들을 받아서 DB에 insert 쿼리문을 이용하여 저장합니다. 회원가입 실습에서 비밀번호를 DB에 저장할 때 보안을 위해 암호화하여 저장했던 것처럼, 댓글의 비밀번호도 동일하게 암호화 처리를 해줍니다.

     

    5. 댓글 삭제 기능

    <?php
    	include './config.php';
    	include './db/db_con.php';
    	
    	// hidden의 값 rno를 받아와 그 값에 해당하는 idx 에 대한 reply 테이블 정보 가져오기
    	$rno = $_POST['rno']; 
    	$sql = mq("select 
    					* 
    			   from 
    					reply 
    			   where 
    					idx='".$rno."'
    			");
    	$reply = $sql->fetch_array();
    	
    	// hidden의 값 b_no를 받아와 그 값에 해당하는 idx 에 대한 board 정보 가져오기
    	$bno = $_POST['b_no'];
    	$sql2 = mq("select 
    					* 
    			    from 
    					board 
    			    where 
    					idx='".$bno."'
    			");
    	$board = $sql2->fetch_array();
    	
    	$pwk = $_POST['pw']; // 모달창에서 입력한 비밀번호
    	$rpw = $reply['pw']; // reply 테이블에 저장된 해쉬값
    	
    	/* 비밀번호를 db의 해쉬값과 비교,  세션값과 db의 name을 비교  */
    	if((password_verify($pwk, $rpw)) && ($userid == $reply['name'])) 
    		{
    			// 테이블 reply에서 인덱스값이 $rno인 값을 찾아 삭제
    			$sql = mq("delete 
    					   from 
    							reply 
    					   where 
    							idx='".$rno."'
    					"); 
    	?>
    			<script>
    				alert("댓글이 삭제 되었습니다.");
    			</script>
    			<meta http-equiv="refresh" content="0 url=/gimal/read.php?idx=<?=$bno?>">
    
    		<?php 
    	}else{ ?>
    			<script>
    				alert('본인의 댓글이 아니거나 비밀번호가 틀립니다');
    				history.back();
    			</script>
    <?php } ?>
    

    post 방식으로 넘어온 데이터들을 받아 해당하는 댓글의 번호를 DB에서 존재하나 확인 후 그 값을 가져오고 거기에 저장된 패스워드와 post로 넘어온 패스워드를 비교하고 현재 세션의 아이디와 DB에서 가져온 아이디의 값이 같은지 확인한 후 이 둘을 모두 만족한다면 해당하는 댓글 번호를 가진 레코드를 삭제하게끔 delete 쿼리문을 작동합니다. 

    삭제가 완료되면 댓글이 삭제되었다는 alert창이 뜨고 만약 본인의 댓글이 아니거나 패스워드가 틀리면 다른 alert창이 뜨게끔 구현했습니다.

     

    해당 내용이 잘 이해가 되지 않는다면 그 전 실습을 참고하시길 바랍니다.

    https://transferhwang.tistory.com/48

     

    [PHP] 게시판 만들기 - 회원가입 구현

    이번 프로젝트는 다음을 참고하였습니다. http://blog.naver.com/PostList.nhn?blogId=bgpoilkj&from=postList&categoryNo=60 S Writer의 IT NOTE : 네이버 블로그 군무원이 꿈이면서 개발도 하는 대학생의 공간 d..

    transferhwang.tistory.com

     

    다음은 댓글 삭제 기능을 구현한 결과 입니다.

     

    댓글 삭제 결과들

     

     

    이렇게 ajax를 이용한 댓글 기능 구현을 마무리했습니다. 이번 실습은 여태까지 실습을 진행하면서 익혔던 다양한 내용들을 종합한 실습이였다고 생각하기에 더 의미있는 실습이라고 생각합니다. 

    여기까지가 제가 PHP를 이용해 간단한 게시판 프로젝트를 진행했던 내용이었습니다. 추후에 내용 추가는 상황을 봐서 올려보도록 하겠습니다. (요즘은 PHP보다 스프링을 공부중이기때문에...)

    부족한 내용이지만 잘 따라와주신 모든 분들 감사합니다 :)

     

    잘못된 부분이나 실습을 진행하면서 궁금한 점은 댓글로 남겨주세요 ㅎㅎ

     

    ※ 완성 코드는 공지사항에 있는 깃헙 주소에서 확인할 수 있습니다. 

     

    PHP 게시판 만들기 시리즈 👇

     

    노력의 천재

    Carpe Diem, Seize the day

    transferhwang.tistory.com

     

    댓글

Designed by Tistory.