이번시간엔 저번시간에 했던 CRUD 페이지 만들기를 참고하여 문의게시판을 만들어볼것 입니다.
전반적인 코드는 아래 게시글과 같습니다. 하지만 변한점이라면 게시글 비밀번호 부분입니다.
게시글 비밀번호를 작성,수정,삭제 할때 인증을 위해 쓰여야 한다는 점을 위주로 참고하시면 좋을것같습니다.
작성,삭제 부분의 Javascript 부분을 중점적으로 참고하시면 유용할 것 같습니다.
https://jamesbexter.tistory.com/entry/웹-개발-CRUD생성읽기수정삭제-페이지-만들기
[웹 개발] CRUD(생성,읽기,수정,삭제) 페이지 만들기
저번시간엔 로그인&로그아웃 인증을 구현하였습니다. https://jamesbexter.tistory.com/entry/2%EC%A3%BC%EC%B0%A8-%EA%B3%BC%EC%A0%9C-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85-%ED%8E%98%EC%9D%B4%EC%A7%80-%EB%A7%8C%EB%93%A4%EA%B8%B0 회원가입
jamesbexter.tistory.com
<목차>
0. 문의 게시판
1. C(create) - qna_write.php
2. R(Read) - qna_read.php
3. U(Update) - qna_update.php
4. D(Delete) - qna_delete.php
< 0 . 문의 게시판 >
문의게시판 버튼은 로그인창 밑 부분에 만들어 주었습니다.
조금 이쁘게 만들고 싶어서 CSS를 추가하여 색,border 의 변화를 주었습니다.
전체적인 디자인은 전에 하였던 페이지를 참고하였습니다.
추가사항이라면 비회원 문의 게시판인 만큼 좋아요 기능과 작성자 기능을 제거하였습니다.
[코드설명]
전체 코드는 전과 크게 다르지 않습니다.
달라진점은 테이블을 새로 생성하였기 때문에 열의 이름을 바꿔준 점입니다.
[qna_list.php]
<?php
include 'dbcon.php';
$current_page= isset($_POST['pageidx']) ? $_POST['pageidx']:1; //기본적으로 페이지는 1페이지로 시작
// 검색 조건과 검색어 가져오기
$stand = isset($_POST['stand']) ? $_POST['stand'] : 'qna_name'; // 기본적으로 제목으로 검색
$search = isset($_POST['search']) ? $_POST['search'] : '';
$startdate = isset($_POST['startdate']) ? $_POST['startdate'] : '2024-01-01';// 날짜 설정 안할시 자동으로 min 값
$enddate = isset($_POST['enddate']) ? $_POST['enddate'] : '2025-12-29';// 날짜 설정 안할시 자동으로 max 값
$sort = isset($_POST['sort']) ? $_POST['sort'] : 1;// 기본적으로 제목으로 정렬
?>
<!DOCTYPE html>
<html lang="en">
<head>
<style> /*a 태그 스타일시트*/
a:link {
color : black;
text-decoration-line: none;
}
a:hover{
text-decoration-line: underline;
}
</style>
<script>
function submitForm(startpage) {
var form = document.createElement('form');
form.method = 'POST';
form.action = '/qna_list.php';
var inputStand = document.createElement('input');
inputStand.type = 'hidden';
inputStand.name = 'stand';
inputStand.value = '<?php echo $stand; ?>';
form.appendChild(inputStand);
var inputStartDate = document.createElement('input');
inputStartDate.type = 'hidden';
inputStartDate.name = 'startdate';
inputStartDate.value = '<?php echo $startdate; ?>';
form.appendChild(inputStartDate);
var inputEndDate = document.createElement('input');
inputEndDate.type = 'hidden';
inputEndDate.name = 'enddate';
inputEndDate.value = '<?php echo $enddate; ?>';
form.appendChild(inputEndDate);
var inputSearch = document.createElement('input');
inputSearch.type = 'hidden';
inputSearch.name = 'search';
inputSearch.value = '<?php echo $search; ?>';
form.appendChild(inputSearch);
var inputPageidx = document.createElement('input');
inputPageidx.type = 'hidden';
inputPageidx.name = 'pageidx';
inputPageidx.value = startpage;
form.appendChild(inputPageidx);
var inputSort = document.createElement('input');
inputSort.type = 'hidden';
inputSort.name = 'sort';
inputSort.value = '<?php echo $sort; ?>';
form.appendChild(inputSort);
document.body.appendChild(form);
form.submit();
}
</script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="holygrail.css" rel="stylesheet" type = "text/css">
<link href="div.css" rel="stylesheet" type = "text/css">
<title>감자대학교 메인페이지</title>
</head>
<body>
<div class="wrapper">
<header>
<div style="text-align:center ; color: #B86824; font-size:20px ; font-weight:bold;transform:translate(0px,10px)">문의 게시판</div>
<div style="text-align: right ;font-weight:bold;transform:translate(-20px,-10px)"><a style="color:purple" href = "index.php">Back</a></div>
</header>
<nav>
<form action="qna_write.php" method="POST"><div style="position:absolute;top:170px;left:10px;width:20%">
<input style="height:40px" type = submit class="submit-btn-blue" value="게시글 작성"></form></div>
</nav>
<main>
<div>
<form style="text-align:left" method="POST">
<select name="stand">
<option value="qna_name">제목</option>
<option value="qna_contents">내용</option>
</select>
<input style="border: solid 1.5px black;width:25%;transform:translate(0px,-1px)" type="text" name ="search" placeholder = "검색" maxlength='30' >
<input style="border: solid 1.5px black" type = submit value="검색">
<select name="sort">
<option value="qna_name">제목순</option>
<option value="qna_date desc">최신순</option>
<option value="qna_date asc">오래된순</option>
</select>
<input name="startdate" type="datetime-local" max="2025-12-29" min="2024-01-01" value="2024-01-01T00:00">
<input name="enddate" type="datetime-local" max="2025-12-29" min="2024-01-01" value="2025-12-30T00:00">
</form>
</div>
<br><hr style="border: solid 1px #696969;height:1px;width:100%">
<table style=border-collapse:collapse;width:100%;>
<tr style="border-bottom:2px solid black;">
<td width="70%">글 제목</td><td style="text-align:center" width="5%" >view</td><td style="text-align:center" width="25%" >날짜</td>
</tr>
<?php // postinfo 테이블 에서 게시글 내용 8개 가져오는 코드 시작.
$sql = "select * from qna_postinfo where qna_date BETWEEN '".$startdate."' AND '".$enddate."' and ".$stand." like '%".$search."%' order by ".$sort; //검색기능을 포함한 sql 구문생성
$result = mysqli_query($dbcon,$sql);
$totalnum=mysqli_num_rows($result); //전체 게시글수
$totalpage=ceil($totalnum/8);//전체 페이지 수
$page_viewed=8; //페이지당 게시글수
$limit_num=$page_viewed*($current_page-1); //limit a,b 에서 a 역할을 할 변수설정
$sql = "select * from qna_postinfo where qna_date BETWEEN '".$startdate."' AND '".$enddate."' and ".$stand." like '%".$search."%' order by ".$sort." limit ".$limit_num.",".$page_viewed;
$result = mysqli_query($dbcon,$sql);
$row=mysqli_fetch_array($result);
for($count=1;isset($row);$count=$count+1){ //게시글을 보여주는 루프 시작 ?>
<tr height="45px" style="border-bottom: 1px solid #696969">
<td width="50%"><a href="qna_read.php?idx=<?php echo $row['idx']; ?>"><?php echo $row['qna_name']; ?></a></td>
<td style="text-align:center" width="5%" height="5%" ><?php echo $row['view']; ?></td>
<td style="text-align:center" width="20%" height="5%" ><?php echo $row['qna_date']; ?></td>
</tr>
<?php $row=mysqli_fetch_array($result);
} ?> </table>
<?php //페이지네이션 하이퍼링크를 만드는 코드
for($startpage=1;$startpage<=$totalpage;$startpage=$startpage+1){
?><a href="#" onclick="submitForm(<?php echo $startpage; ?>);">[<?php echo $startpage; ?>]</a><?php
} ?>
</main>
</body>
</html>
< 1. C(create) - qna_write.php >
우선 qna 작성 페이지 입니다.
디자인은 전에 했던 post_write.php 페이지와 동일하게 하였습니다.
게시글을 작성하기위해서 왼쪽 하단에 게시글의 비밀번호를 입력해주어야 하는 과정을 더했습니다.
이후 qna_write_prc.php 에서 DB에 있는 qna_postinfo 테이블로 저장해주는 과정을 거쳤습니다.
[코드설명]
오른쪽 하단에 비밀번호를 적어준 후 작성이 되도록 하였습니다.
만약 깜빡하고 비밀번호를 안적는다 하더라도 자바스크립트를 통해 알람창을 띄우기 때문에 페이지 이동이 없어서 전에 쓰던내용이 날아갈 걱정은 안할수 있게되었습니다!
[qna_write.php]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="div.css" rel="stylesheet" type = "text/css">
<title>Posting</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
$('form').on('submit', function(event) { //비밀번호를 안쓰면 못넘어가게 함.
var password = $('input[name="qna_password"]').val();
if (password === '') {
event.preventDefault();
alert('비밀번호를 적어주세요.');
}
});
});
</script>
<style> /*a 태그 스타일시트*/
a:link {
color : black;
text-decoration-line: none;
}
a:hover{
text-decoration-line: underline;
}
textarea{
font-size:1.5em;
}
</style>
</head>
<body>
<div style="text-align:center" class="yellowfull">
<div style="position:absolute;font-weight:bold; right:60px; top: 45px;">
<a href="qna_list.php">BACK</a>
</div>
<form action="qna_write_prc.php" method="POST">
<input type="text" name="qna_name" placeholder="제목" maxlength='20' style="text-align:center;position:absolute;background-color:white; width:60%; height:10%;transform:translate(33%,50%);font-size:20px" class="login-box">
<textarea type="text" name="qna_contents" placeholder="내용" maxlength='750' style="text-align:center;position:absolute;background-color:white; width:60%; height:65%;transform:translate(33%,25%)" class="login-box"></textarea>
<div style="position:absolute;bottom:20px;right:39.5%;width:20%;">
<input type="password" name ="qna_password" placeholder = "Enter Post PassWord" maxlength='10' class="password-form" style="position:absolute;right:130%;bottom:20px">
<input style="height:30px;background-color:#dcdcdc" type = submit class="submit-btn" value="작성"></div>
</div>
</body>
</html>
[qna_write_prc.php]
<?php
include 'dbcon.php';
$qna_name=$_POST['qna_name'];
$qna_contents=$_POST['qna_contents'];
$qna_password=$_POST['qna_password'];
if($qna_name==NULL||$qna_contents==NULL){
echo "<script>alert('작성하지 않은 내용이 있습니다!');
window.location.href='/'
</script>";
exit();
}else if($qna_password==NULL){
echo "<script>alert('비밀번호를 입력하셔야 합니다!');
window.location.href='/'
</script>";
}
else{
$sql = "insert into qna_postinfo (qna_name,qna_contents,qna_password) values ('".$qna_name."','".$qna_contents."',".$qna_password.")";
$result = mysqli_query($dbcon,$sql);
$sql="UPDATE postinfo set postdate=CONVERT_TZ(NOW(), '+00:00', '+09:00') where post_name='".$post_name."'";
$result = mysqli_query($dbcon,$sql); //서버 시간대가 UTC 라서 9시간을 더하기.
echo "<script>alert('게시글이 작성되었습니다!!');
location.href='/index.php'
</script>";
exit();
}
?>
< 2. R(Read) - qna_read.php >
Read 페이지 또한 전과는 크게 다른점이 없습니다.
좋아요 기능이 제거되고 Table,Column명 바뀜 이외엔 코드상 크게 변화가 없습니다.
qna_read.php |
![]() |
[코드설명]
이 부분에서 가장 크게 달라진 점은 head에 delete.php 를 위한 스크립트가 삽입되었다는 점입니다.
이 점은 4번 D(Delete) 에서 설명할 터이니 가독성을 위해 생략해주겠습니다.
[qna_read.php]
<?php
include 'dbcon.php';
$idx=$_GET['idx'];
?>
<!DOCTYPE html>
<html lang="en">
<head>
//메타태그 , jquery,font에 필요한 링크.
<script>
if (!window.w){
<?php
$sql = "update qna_postinfo set view=view+1 where idx=".$idx; //열람시 조회수 상승 기능
mysqli_query($dbcon,$sql);
?>
window.w=1;
}
</script>
<script>
//여기는 delete 를 위한 코드이므로 생략!
</script>
<style> /*a 태그 스타일시트*/
a:link {
color : black;
text-decoration-line: none;
}
a:hover{
text-decoration-line: underline;
}
</style>
</head>
<body>
<div style="text-align:center" class="yellowfull">
<div style="position:absolute;font-weight:bold; right:60px; top: 45px;">
<a href="qna_list.php">BACK</a>
</div>
<?php
$sql = "select * from qna_postinfo where idx='".$idx."'"; //게시물 내용을 가져오는 sql 구문
$result = mysqli_query($dbcon,$sql);
$row=mysqli_fetch_array($result);
?>
<div style="position:absolute;background-color:white; width:60%; height:10%;transform:translate(35%,50%)" class="login-box">
<div style="text-align:center;">
<?php echo $row['qna_name']; ?>
</div>
</div>
<div style="position:absolute;background-color:white; width:60%; height:65%;transform:translate(35%,25%)" class="login-box">
<?php echo $row['qna_contents']; ?>
</div>
<form action="qna_delete.php" method="POST" id="qna_del_btn">
<input type="hidden" name="idx" value="<?php echo $idx ?>">
<div style="position:absolute;bottom:20px;right:28%;width:20%;">
<input style="height:30px;background-color:#dcdcdc" type = submit class="submit-btn" value="삭제"></div></form>
<form action="qna_update.php" method="GET">
<input type="hidden" name="idx" value="<?php echo $idx ?>">
<div style="position:absolute;bottom:20px;left:30%;width:20%;">
<input style="height:30px;background-color:#dcdcdc" type = submit class="submit-btn" value="수정"></div></form>
</div>
</body>
</html>
< 3.U(update)-qna_update.php >
read.php 에서 수정버튼을 클릭하면 qna_update.php 로 이동하게 됩니다.
수정할부분을 고치고 좌측 하단에 비밀번호를 입력합니다.
이 비밀번호를 통해 qna_update_prc.php 에서 인증절차를 거친후 수정이 이루어집니다.
만약 인증이 안될시 "권한이 없습니다" 라는 메세지가 뜬 후 index.php 로 돌아가지게 됩니다.
[코드설명]
우선 qna_update.php 는 form 태그 안에 인증을 위한 ver_password 를 입력하는 부분이 생겼습니다!
[qna_update.php]
<?php
include 'dbcon.php';
$idx=$_GET['idx']; // DB에서 update 를 위한 인증정보 가져오기
$sql = "select * from qna_postinfo where idx=".$idx;
$result = mysqli_query($dbcon,$sql);
$row=mysqli_fetch_array($result);
$qna_name=$row['qna_name'];
$qna_contents=$row['qna_contents'];
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="div.css" rel="stylesheet" type = "text/css">
<title>Posting</title>
<style> /*a 태그 스타일시트*/
a:link {
color : black;
text-decoration-line: none;
}
a:hover{
text-decoration-line: underline;
}
textarea{
font-size:1.5em;
}
</style>
</head>
<body>
<div style="text-align:center" class="yellowfull">
<div style="position:absolute;font-weight:bold; right:60px; top: 45px;">
<a href="page.php">BACK</a>
</div>
<form action="qna_update_prc.php" method="POST">
<input type="hidden" name="idx" value=<?php echo $idx; ?>>
<input type="text" name="qna_name" value="<?php echo $qna_name ?>" placeholder="제목" maxlength='20' style="text-align:center;position:absolute;background-color:white; width:60%; height:10%;transform:translate(33%,50%);font-size:20px" class="login-box">
<textarea type="text" name="qna_contents" placeholder="내용" maxlength='750' style="text-align:center;position:absolute;background-color:white; width:60%; height:65%;transform:translate(33%,25%)" class="login-box"><?php echo $qna_contents; ?></textarea>
<div style="position:absolute;bottom:20px;right:39.5%;width:20%;">
<input type="password" name ="ver_password" placeholder = "Enter Post PassWord" maxlength='10' class="password-form" style="position:absolute;right:130%;bottom:20px">
<input style="height:30px;background-color:#dcdcdc" type = submit class="submit-btn" value="작성"></div>
</form>
</div>
</body>
</html>
이후 qna_update_prc.php 에선 인증절차를 추가해주었습니다!
[qna_update_prc.php]
<?php
include 'dbcon.php';
$idx=$_POST['idx']; // DB에서 update 를 위한 인증정보 가져오기
$sql = "select qna_password from qna_postinfo where idx=".$idx;
$result = mysqli_query($dbcon,$sql);
$row=mysqli_fetch_array($result);
$qna_name=$_POST['qna_name'];
$qna_contents=$_POST['qna_contents'];
$ver_password=$_POST['ver_password'];
// idx가 유효한지 확인
if (!$idx) {
echo "<script>alert('잘못된 접근입니다.'); location.href='/index.php';</script>";
exit();
}
if($ver_password==$row['qna_password']){ //수정 시작전에 글의 비밀번호와 작성된 비밀번호가 같은지 확인
$sql = "update qna_postinfo set qna_name='".$qna_name."',qna_contents='".$qna_contents."' where idx=".$idx;
$result = mysqli_query($dbcon,$sql);
//인증 완료시 게시글 수정
echo "<script>alert('게시글이 수정되었습니다!!');
location.href='/index.php'
</script>";
exit();
}else{ //인증 X 일때 권한이 없다한 후 index.php 로 리다이렉션
echo "<script>alert('권한이 없습니다.');
location.href='/index.php'
</script>";
exit();
}
?>
< 4. D(Delete) - qna_delete.php >
Delete 는 두가지 페이지에서 이루어집니다.
qna_read.php 에서 삭제버튼을 누르면 prompt 창이 뜹니다.
거기에 게시물의 비밀번호를 입력한 후 그 비밀번호 정보와 게시물의 idx 를 qna_delete.php 로 보내주게 됩니다.
이후 인증절차를 통과하게 되면 삭제가 완료됩니다.
[코드설명]
위에 read 부분에서 언급하였듯 qna_read.php 의 head 태그부분에 Jquery 코드를 삽입해주었습니다.
id=qna_del_btn 인 버튼을 누르면 스크립트가 동작하게 되어 prompt 창에 입력된 값을 POST요청으로 qna_delete.php로 보내주게 되는 코드입니다.
[php_read.php 중 head 태그 부분]
<script>
document.addEventListener('DOMContentLoaded', function() {
// Get the delete button
var deleteButton = document.getElementById('qna_del_btn');
if (deleteButton) {
deleteButton.addEventListener('click', function(event) {
event.preventDefault(); // Prevent the default form submission
var idx = document.querySelector('input[name="idx"]').value;
var ver_password = prompt("비밀번호를 입력하세요:");
if (ver_password !== null) {
// Create a form element
var form = document.createElement("form");
form.method = "POST";
form.action = "qna_delete.php"; // 서버로 전송할 파일
// Create hidden input elements for data
var idxInput = document.createElement("input");
idxInput.type = "hidden";
idxInput.name = "idx";
idxInput.value = idx;
form.appendChild(idxInput);
var passwordInput = document.createElement("input");
passwordInput.type = "hidden";
passwordInput.name = "ver_password";
passwordInput.value = ver_password;
form.appendChild(passwordInput);
// Append the form to the body and submit
document.body.appendChild(form);
form.submit();
}
});
}
});
</script>
이후 qna_delete.php 에서 인증절차 이후 삭제가 이루어지게 됩니다.
<?php
include 'dbcon.php';
$idx=$_POST['idx']; // DB에서 update 를 위한 인증정보 가져오기
$sql = "select qna_password from qna_postinfo where idx=".$idx;
$result = mysqli_query($dbcon,$sql);
$row=mysqli_fetch_array($result);
$ver_password=$_POST['ver_password'];
if($row['qna_password']==$ver_password){ //글 비밀번호 인증절차
$sql = "delete from qna_postinfo where idx=".$idx;
$result = mysqli_query($dbcon,$sql);
//인증 완료시 게시글 삭제
echo "<script>alert('게시글이 삭제되었습니다!!');
location.href='/index.php'
</script>";
exit();
}else{ //인증 X 일때 권한이 없다한 후 index.php 로 리다이렉션
echo "<script>alert('권한이 없습니다.');
location.href='/index.php'
</script>";
exit();
}
?>
긴 글 읽어주셔서 감사합니다!
'웹개발(PHP-Mysql)' 카테고리의 다른 글
어느날 갑자기 MySQL 비밀번호가 틀렸다고 뜰때 대처법 (0) | 2024.09.29 |
---|---|
[웹 개발-Jquery] 비밀번호 가시화 기능 (0) | 2024.07.21 |
[웹 개발-PHP] 조회수 & 좋아요 기능 구현 (2) | 2024.07.21 |
[웹 개발-PHP] 파일 업로드 기능 구현(+확장자 체크) (0) | 2024.07.20 |
[웹 개발-PHP] Pagination 기능 추가(+ 보완할 점) (0) | 2024.07.17 |