ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [PHP] 게시판 만들기 - 글쓰기 기능 구현 ②
    프로그래밍/PHP 2020. 2. 13. 16:09

    지난 실습에 이어 비밀글 기능을 추가하기 위해 필요한 몇 가지 수정사항과 추가사항들을 같이 구현해보는 시간을 가져보겠습니다. 

    1. list.php 수정

    비밀글 체크박스에 체크된 예제

    저번 실습을 통해 위와 같이 글쓰기 화면을 구현하였고 비밀 글 체크박스에 체크를 하고 글쓰기 버튼을 눌렀을 때 해당 게시글은 비밀 글이 되어야 합니다. 따라서 공개 글과 비밀 글을 눈으로 봤을때 구분할 수 있도록 다음과 같이 만들어 줄 예정입니다.

     

    체크됐을때 결과

    비밀 글은 위과 같이 제목 옆에 자물쇠 모양을 두어 공개 글과 구분할 수 있도록 만들어줍니다. 이를 위해서 list.php 일부분을 수정해주어야 하는데 코드는 다음과 같습니다.

        <!-- 글 목록 가져오기 -->
    			      <tbody>
    			      	<tr>
    			          <td width="70"><?=$board['idx']; ?></td>
    			          <td width="500">
    			          <!-- 비밀 글 가져오기 -->	 
    			          <?php 
    			          	$lockimg="<img src='./img/lock.png' alt='lock' title='lock' width='18' height='18'>";
    			          	if($board['lock_post']=="1"){ // lock_post 값이 1이면 잠금
    			          ?>
    			          		<span class="lock_check" style="cursor:pointer" data-idx="<?=$board['idx']?>" ><?=$title?> <?=$lockimg?></span>
    			          <!-- 일반 글 가져오기 -->
    			          <?php 
    			          	}else{	// 아니면 공개 글
    			          ?>
    			          		<span class="read_check" style="cursor:pointer" data-action="./read.php?idx=<?=$board['idx']?>" ><?=$title?></span> 
    			          <?php 		
    			          	}
    			          ?>
    			          <td width="120"><?=$board['name'];?></td>
    			          <td width="100"><?=$board['date'];?></td>
    			          <td width="100"><?=$board['hit']; ?></td>
    			        </tr>
    			      </tbody>

    여기서 가장 핵심은 <span> 태그의 class 명인 'lock_check', 'read_check' 와 'data-idx' 입니다. 기억해둡시다!

    자신이 원하는 자물쇠 모양의 이미지를 인터넷에서 다운받고 이미지 경로를 설정해줍니다. 크기는 태그 속성으로 설정해주면 되므로 걱정안하셔도 됩니다. DB에서 가져온 lock_post이 값이 1인지 조건문을 통해서 확인하고, 이 조건이 참이라면 위의 결과와 같이 자물쇠 이미지와 함께 글의 제목을 가져옵니다. 반면에 조건문이 거짓이라면 공개 글을 가져올 수 있게끔 설정했습니다. 

     

    2. 모달창 구현

    비밀 글을 클릭했을 때는 글의 비밀번호를 입력하라는 모달창을 띄워야하고, 공개 글을 눌렀을 때는 해당 글을 읽을 수 있도록 페이지가 넘어가게끔 이벤트를 구현해야 합니다. 먼저 모달창을 먼저 구현해봅시다.

    <!-- 비밀 글 모달창 양식 구현-->
    		<div class="modal fade" id="modal_div">
    			<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="./ck_read.php?idx=" data-action="./ck_read.php?idx=">
    							<p>비밀번호  <input type="password" name="pw_chk" /> <input type="submit" class="btn btn-primary" value="확인" /></p>
    						</form>
    					</div>
    			  	</div>
    		  	</div>
    		</div>
    		<!-- 비밀 글 모달창 구현 끝-->

    위의 코드는 부트스트랩을 이용하여 만든 모달 창 코드입니다. 모달창의 body 부분에 form을 구현하여 입력받은 비밀번호를 비밀번호 비교를 위한 코드인 ck_read.php로 전송하게끔 구현하였습니다. data-action이 의미하는 바는 예전 실습에서 설명하였으므로 참고하시길 바랍니다. 여기서도 가장 상위 div 태그의 id인 'modal_div'와 form 태그의 id 'modal_form'을 기억해두시길 바랍니다. (+ input 태그의 'pw_chk' 도 기억해둡시다! 다음 실습에서 한번 더 언급하겠습니다.) 

     

    모달창 구현 결과

     

    3. 이벤트 구현

    이제 모달창을 구현하였으므로 비밀 글과 공개 글의 이벤트를 제이쿼리를 이용하여 구현해보도록 합시다. 

    <script>
    		<!-- 비밀글 클릭시 모달창을 띄우는 이벤트 -->
    		$(function(){
    		    $(".lock_check").click(function(){
    				$("#modal_div").modal();
    				<!-- 주소에 data-idx(idx)값을 더하기 -->
    				var action_url = $("#modal_form").attr("data-action")+$(this).attr("data-idx")
    				$("#modal_form").attr("action",action_url);
    			});
    		});

    아까 기억하라고 했었던 사항들을 기억하고 있으시다면 위의 코드를 이해하기 쉬우실겁니다. lock_check가 클릭 이벤트가 발생하면, 'modal_div' id를 가진 div 태그가 모달창이 띄어지게끔 이벤트를 발생하는 코드입니다.

    그 다음 'modal_form'의 'data-action' 속성에 'data-idx' 속성을 더하고 그 주소값을 action_url에 저장하고 그 주소로 이동(액션) 이벤트가 발생하도록 하는 코드입니다. 

     

    <!-- 일반 글 클릭시 해당 idx의 read 페이지로 이동하는 이벤트 -->
    		$(function(){
    		    $(".read_check").click(function(){
    			    var action_url = $(this).attr("data-action");
    			    $(location).attr("href",action_url);
    			});
    		});
    		</script>

    마찬가지로 위의 코드도 read_check가 클릭 이벤트가 발생하면 'data-action' 속성을 action_url에 저장하고 해당 주소로 이동 할 수 있도록 만들어줍니다.

     

    4. write_ok.php 수정

    먼저 전체 코드는 다음과 같습니다. 추가된 부분을 차례대로 알아봅시다.

    <?php
    	include "./config.php";
    	include "./db/db_con.php";
    	
    	$name = $userid;
    	$date = date('Y-m-d');
    	$userpw = password_hash($_POST['pw'], PASSWORD_DEFAULT); // 입력받은 패스워드를 해쉬값으로 암호화
    	$title = $_POST['title'];
    	$content = $_POST['content'];
    
    	if(isset($_POST['lockpost'])){
    		$lo_post = '1';
    	}else{
    		$lo_post = '0';
    	}
    
    	mq("alter table board auto_increment =1"); //auto_increment 값 초기화 (삭제 시 번호 비지 않게 하기 위해서)
    	
    	mq("INSERT 
    			board
    		SET	
    			name = '".$name."', 
    			pw = '".$userpw."', 
    			title = '".$title."', 
    			content = '".$content."',  
    			date ='".$date."',
    			lock_post = '".$lo_post."'
    	");
    ?>
    	<script>
    		alert("글쓰기 완료되었습니다.");
    		location.href = 'list.php';
    	</script>

     

    	if(isset($_POST['lockpost'])){
    		$lo_post = '1';
    	}else{
    		$lo_post = '0';
    	}

    isset함수를 통해서 post 방식으로 받아온 lockpost의 값이 존재하는지 확인합니다. 즉 글쓰기를 할때 비밀 글 체크박스에 체크를 했다면 값이 존재하므로 $lo_post에 1을 저장하고 값이 없다면 0으로 저장하는 코드입니다.

     

    mq("alter table board auto_increment =1");

    이 코드는 지금은 필요하지 않지만 나중에 글 삭제 기능을 구현할때 필요하므로 미리 구현해봤습니다. auto_increment 값을 1로 초기화하는 코드입니다. 왜 이런 기능이 필요할까요?

     

    게시판에 16개의 글이 있고 글 번호가 15번인 글을 삭제한다고 가정해봅시다. 15번 글을 삭제하고 새로운 글을 쓴다면 그 글의 번호는 몇번이 될까요? 당연히 16번이라고 생각하시겠지만 불행히도 글 번호는 17번째가되고 15번은 비어버리게 됩니다. 이러한 사태를 막기위해서 위와 같이 auto_increment를 1로 초기화 해주어야 합니다.

     

    mq("INSERT 
    			board
    		SET	
    			name = '".$name."', 
    			pw = '".$userpw."', 
    			title = '".$title."', 
    			content = '".$content."',  
    			date ='".$date."',
    			lock_post = '".$lo_post."'
    	");

    마지막으로 form 태그에서 입력받은 데이터들을 board 테이블로 저장하기 위한 SQL 코드에 비밀 글에 관련된 데이터인 $lo_post를 추가해줍니다. 

     

    5. 비밀번호 비교하기

    이제 남은 일은 모달창에서 비밀번호를 입력했을 때, 입력한 비밀번호가 DB에 저장된 비밀번호와 일치하는지 비교하는 기능을 구현하는 것입니다.

     

    <?php
    	include_once "./db/db_con.php"; 
    ?>
    	<?php
    		$bno = $_GET['idx']; // $bno idx값을 받아와 넣음
    		/* 받아온 idx값의 행 정보를 가져옴 */
    		$sql = mq("select 
    						* 
    				   from 
    						board 
    				   where 
    						idx='".$bno."'
    				"); 
    		$board = $sql->fetch_array();
    	?>
    		<!-- DB의 비밀번호($bpw)와 모달창의 비밀번호($pwk)를 비교 -->
    		 <?php
    		 	$bpw = $board['pw'];
    	
    		 	if(isset($_POST['pw_chk'])) 
    		 	{
    		 		$pwk = $_POST['pw_chk']; 
    				if(password_verify($pwk,$bpw)) 
    				{
    					$pwk == $bpw;
    				?>
    					<!-- pwk와 bpw값이 같으면 read.php로 보내고 -->
    					<script>
    						location.replace("read.php?idx=<?=$board["idx"] ?>");
    					</script>
    				<?php 
    				}else{ ?>
    					<!--- 아니면 비밀번호가 틀리다는 메시지를 보여줌 -->
    					<script>
    						alert('비밀번호가 틀립니다');
    					</script>
    				<?php } } ?>

    링크에서 GET방식으로 글 번호인 idx의 값을 받고 SQL문을 통해 해당 idx에 해당하는 데이터의 모든 정보를 가져오고 fetch_array()를 통해 해당 데이터의 정보를 배열화합니다. 그 다음 게시글에 비밀번호가 있는지 확인합니다. 비밀번호가 존재한다면, DB에 저장된 패스워드는 보안을 위해 해쉬값으로 바뀌어있으므로 모달 창에서 입력한 비밀번와 일치하는지 비교하기 위해서 password_verify()함수를 이용합니다. 그래서 그 둘의 값이 일치한다면, 해당 게시글을 읽을 수 있도록 페이지를 이동합니다. 만약 비밀번호가 일치하지 않는다면, alert 경고창을 이용하여 비밀번호가 틀리다고 안내문을 띄어주는 코드입니다. 

     

    이렇게 글쓰기 화면과 비밀 글을 포함한 글쓰기 기능 구현을 완료하였습니다. 여태까지 진행했던 과정중에 가장 길고 어렵게 느껴질 실습이었다고 생각합니다. 천천히 잘 따라해보시고 결과물을 확인해보시길 바랍니다! 다음 실습에서는 이렇게 작성한 게시글을 읽을 수 있게 만들어보는 시간을 가지도록 하겠습니다.

     

    긴 글 읽느라 고생많으셨습니다. 감사합니다 :) 

     

    게시판 만들기 시리즈 👇

     

    노력의 천재

    Carpe Diem, Seize the day

    transferhwang.tistory.com

     

    댓글

Designed by Tistory.