8. PHP 게시판 만들기, write 제작 4

2015. 4. 8. 22:28
저자 : Kurien

주의: 본 게시판은 보안을 생각하지 않고 만들어졌으므로 실제로 사용되어서는 안되는 코드입니다.

공부할 때 게시판이 이처럼 동작한다는 정도로만 이해해주세요.


오늘은 전 포스팅에서 설명하지 못한 write_update.php에 대해서 적어보겠습니다.

어제와 같은 파일을 받아주세요!


20150407_project.zip


write_update.php를 열어봅시다.


<?php

require_once("../dbconfig.php");


//$_POST['bno']이 있을 때만 $bno 선언

if(isset($_POST['bno'])) {

$bNo = $_POST['bno'];

}


//bno이 없다면(글 쓰기라면) 변수 선언

if(empty($bNo)) {

$bID = $_POST['bID'];

$date = date('Y-m-d H:i:s');

}


//항상 변수 선언

$bPassword = $_POST['bPassword'];

$bTitle = $_POST['bTitle'];

$bContent = $_POST['bContent'];


//글 수정

if(isset($bNo)) {

//수정 할 글의 비밀번호가 입력된 비밀번호와 맞는지 체크

$sql = 'select count(b_password) as cnt from board_free where b_password=password("' . $bPassword . '") and b_no = ' . $bNo;

$result = $db->query($sql);

$row = $result->fetch_assoc();

//비밀번호가 맞다면 업데이트 쿼리 작성

if($row['cnt']) {

$sql = 'update board_free set b_title="' . $bTitle . '", b_content="' . $bContent . '" where b_no = ' . $bNo;

$msgState = '수정';

//틀리다면 메시지 출력 후 이전화면으로

} else {

$msg = '비밀번호가 맞지 않습니다.';

?>

<script>

alert("<?php echo $msg?>");

history.back();

</script>

<?php

exit;

}

//글 등록

} else {

$sql = 'insert into board_free (b_no, b_title, b_content, b_date, b_hit, b_id, b_password) values(null, "' . $bTitle . '", "' . $bContent . '", "' . $date . '", 0, "' . $bID . '", password("' . $bPassword . '"))';

$msgState = '등록';

}


//메시지가 없다면 (오류가 없다면)

if(empty($msg)) {

$result = $db->query($sql);

//쿼리가 정상 실행 됐다면,

if($result) {

$msg = '정상적으로 글이 ' . $msgState . '되었습니다.';

if(empty($bNo)) {

$bNo = $db->insert_id;

}

$replaceURL = './view.php?bno=' . $bNo;

} else {

$msg = '글을 ' . $msgState . '하지 못했습니다.';

?>

<script>

alert("<?php echo $msg?>");

history.back();

</script>

<?php

exit;

}

}


?>

<script>

alert("<?php echo $msg?>");

location.replace("<?php echo $replaceURL?>");

</script>


이번에도 추가된 부분은 빨간색으로 바꿔뒀습니다.

차근차근 알아보겠습니다.


//$_POST['bno']이 있을 때만 $bno 선언

if(isset($_POST['bno'])) {

$bNo = $_POST['bno'];

}


//bno이 없다면(글 쓰기라면) 변수 선언

if(empty($bNo)) {

$bID = $_POST['bID'];

$date = date('Y-m-d H:i:s');

}


먼저 이 부분에서도 write.php처럼 $_POST['bno']이 있는지 확인합니다.

write.php에서와 다른 점이라면 $_GET['bno']에서 $_POST['bno']으로 바뀌었다는 점 뿐이겠네요.

get과 post의 차이는 아실거라고 생각하고 넘어가겠습니다.


그 아래 보시면 if(empty($bno)) {}이라는 조건문이 있는데, isset과 달리 이번에는 $bNo이라는 변수에 값이 없다면 출력되는 부분입니다.

$bNo이 없는건 글을 쓸 때 뿐이므로 $bNo이 없을 때만 글을 쓸 때 필요한 $bID와 $date를 선언합니다.


//글 수정

if(isset($bNo)) {

//수정 할 글의 비밀번호가 입력된 비밀번호와 맞는지 체크

$sql = 'select count(b_password) as cnt from board_free where b_password=password("' . $bPassword . '") and b_no = ' . $bNo;

$result = $db->query($sql);

$row = $result->fetch_assoc();

//비밀번호가 맞다면 업데이트 쿼리 작성

if($row['cnt']) {

$sql = 'update board_free set b_title="' . $bTitle . '", b_content="' . $bContent . '" where b_no = ' . $bNo;

$msgState = '수정';

//틀리다면 메시지 출력 후 이전화면으로

} else {

$msg = '비밀번호가 맞지 않습니다.';

?>

<script>

alert("<?php echo $msg?>");

history.back();

</script>

<?php

exit;

}

//글 등록

} else {


이번엔 이 부분을 설명하겠습니다.

자주 봤던 isset($bNo)을 이용해서 글 수정 상태일 때만 실행되는 부분입니다.

먼저 select문을 이용해서 board_free 테이블 내에 같은 b_no(글번호), 같은 b_password(글 비밀번호)가 존재하는지 찾습니다.


만약 존재한다면 $row['cnt']의 값은 1이 출력되겠죠?

b_no은 기본키로 중복된 값이 있을 수 없으니깐요,


여기서 글이 없거나, b_password와 password($bPassword)의 값이 일치하지 않는다면 $row['cnt']가 0이 되는데요.

없는 글번호라면 일반적인 사용자가 write_update.php까지 접근할 수 없습니다.

직접 form을 변형해서 write_update.php로 post로 던져주지 않는 이상은요.


자세한건 나중에 보안쪽에서 함께 다루도록 하구요, 어쨌든 정상적인 과정이라면 비밀번호가 틀릴 때 0이라는 값이 나오게 되므로

else를 이용해서 $msg에 '비밀번호가 맞지 않습니다.' 라는 값을 넣어주고 $msg를 출력해줬습니다.


그리고 전에 빠진 부분이 있었는데, "exit" 이 키워드를 써야만 프로그램이 여기서 종료 됩니다.

만약 exit를 빼고 넘어가버리면 프로그램이 중지되지 않고 끝까지 실행된 후 종료됩니다.

필수 사항이니 꼭 넣어주세요!


정상적으로 1이 나오게 된다면 비밀번호가 맞다는 말이므로 update문을 이용해서 수정된 내용을 갱신시켜줍니다.


그리고 $msgState라는 변수를 새로 선언 했는데,

update문을 사용했다는 말은 수정을 했다는 말이므로 뒤에 나올 메시지의 값을 수정으로 출력할 때 쓰려고 적었습니다.


글 수정이 아니라면 else를 통해 글 등록 부분으로 넘어갑니다.

기존에 만든 부분이지만 여기서도 조금 수정한 부분이 있습니다.


$msgState = '등록';


이 $msgState도 글 수정에 있던 $msgState = '수정';과 같은 역할을 합니다.

아래 나올 내용에서 더 알아보고 여기선 넘어갑시다.


//메시지가 없다면 (오류가 없다면)

if(empty($msg)) {}


이 부분은 지금 보니 딱히 필요한 부분은 아닌데요.

나중에 <script>alert("<?php echo $msg?>"); history.back();</script> 이 부분을 한번에 사용할 생각이긴 한데

일단은 그냥 넘어가셔도 될 것 같습니다.


여기까지 왔다면 update문이든 insert 문이든 상관 없이 $result = query 전송 부분이 실행됩니다.

전에 설명 했듯이 쿼리 결과가 성공이라면 $result = TRUE가 되구요,

실패하면 FALSE가 되겠죠.


성공을 했다면 아래의 코드가 실행됩니다.


$msg = '정상적으로 글이 ' . $msgState . '되었습니다.';

if(empty($bNo)) {

$bNo = $db->insert_id;

}

$replaceURL = './view.php?bno=' . $bNo;


여기서 $msgState의 용도가 나오네요.

만약 수정을 했다면 $msg는 '정상적으로 글이 수정되었습니다.'라는 문장이 될 것이고,

글을 썼다면 '정상적으로 글이 등록되었습니다.'라는 문장이 됩니다.


아래 있는 if(empty($bNo)) {}은 아까 본것처럼 $bNo의 값이 없다면(글쓰기라면) 실행하는 부분입니다.

글쓰기였다면 $bNo = $db->insert_id;를 실행해서 $bNo의 값을 받아옵니다.


그 다음 $replaceURL을 작성해주죠.


$msg = '글을 ' . $msgState . '하지 못했습니다.';


만약 $result가 FALSE라면 글을 수정 or 등록하지 못했습니다. 라는 메시지를 보여주고 이전 화면으로 되돌아갑니다.


<script>

alert("<?php echo $msg?>");

location.replace("<?php echo $replaceURL?>");

</script>


정상적으로 실행 되었던 상태라면 위의 코드를 가지고 view.php 화면으로 돌아가게 되는거죠.


게시판도 하나의 프로그램이라서 나름 복잡하다면 복잡합니다.

이해하기 힘든 부분이 있을 수도 있구요.


나름 설명 길게 열심히 달았다고 생각하니, 꼭 몇번 읽어보시구요.

그래도 이해가 잘 안된다 싶으면 댓글 남겨주세요!


더 좋은 방법, 틀린 부분이 있다면 지적은 환영입니다!