17. PHP 게시판 만들기, view 제작 6

2015. 5. 1. 01:39
저자 : Kurien

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

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


요즘들어 피곤하네요.

야근도 잦고, 잠도 늦게 자서 그런지 힘이 읎네요 ㅋ


그래도 적을건 적어야죠, ㅎㅎ

project 파일은 앞전의 게시글에 함께 있으니 그 파일로 하시면 되겠습니다.


오늘 수정할 부분은 댓글을 업데이트(쓰기, 수정, 삭제) 하는 부분인 comment_update.php입니다.

저번에 수정했던 comment.php보다는 나을 수도 있지만, 이 부분도 복잡하다고 생각합니다.

차근차근 따라해주세요!


<?php

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

$w = '';

$coNo = 'null';

//2Depth & 수정 & 삭제

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

$w = $_POST['w'];

$coNo = $_POST['co_no'];

}

//공통 변수

$bNo = $_POST['bno'];

$coPassword = $_POST['coPassword'];

if($w !== 'd') {//$w 변수가 d일 경우 $coContent와 $coId가 필요 없음.

$coContent = $_POST['coContent'];

if($w !== 'u') {//$w 변수가 u일 경우 $coId가 필요 없음.

$coId = $_POST['coId'];

}

}

if(empty($w) || $w === 'w') { //$w 변수가 비어있거나 w인 경우

$msg = '작성';

$sql = 'insert into comment_free values(null, ' .$bNo . ', ' . $coNo . ', "' . $coContent . '", "' . $coId . '", password("' . $coPassword . '"))';


if(empty($w)) { //$w 변수가 비어있다면,

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

$coNo = $db->insert_id;

$sql = 'update comment_free set co_order = co_no where co_no = ' . $coNo;

}

} else if($w === 'u') { //작성

$msg = '수정';

$sql = 'select count(*) as cnt from comment_free where co_password=password("' . $coPassword . '") and co_no = ' . $coNo;

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

$row = $result->fetch_assoc();

if(empty($row['cnt'])) { //맞는 결과가 없을 경우 종료

?>

<script>

alert('비밀번호가 맞지 않습니다.');

history.back();

</script>

<?php 

exit;

}

$sql = 'update comment_free set co_content = "' . $coContent . '" where co_password=password("' . $coPassword . '") and co_no = ' . $coNo;

} else if($w === 'd') { //삭제

$msg = '삭제';

$sql = 'select count(*) as cnt from comment_free where co_password=password("' . $coPassword . '") and co_no = ' . $coNo;


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

$row = $result->fetch_assoc();

if(empty($row['cnt'])) { //맞는 결과가 없을 경우 종료

?>

<script>

alert('비밀번호가 맞지 않습니다.');

history.back();

</script>

<?php 

exit;

}

$sql = 'delete from comment_free where co_password=password("' . $coPassword . '") and co_no = ' . $coNo;


} else {

?>

<script>

alert('정상적인 경로를 이용해주세요.');

history.back();

</script>

<?php 

exit;

}

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

if($result) {

?>

<script>

alert('댓글이 정상적으로 <?php echo $msg?>되었습니다.');

location.replace("./view.php?bno=<?php echo $bNo?>");

</script>

<?php

} else {

?>

<script>

alert('댓글 <?php echo $msg?>에 실패했습니다.');

history.back();

</script>

<?php

exit;

}

?>


이번에도 빨간색 부분만 나눠서 설명해드리겠습니다.

빨간색인 부분은 추가 혹은 수정이 된 부분입니다.


$w = '';

$coNo = 'null';


//2Depth & 수정 & 삭제

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

$w = $_POST['w'];

$coNo = $_POST['co_no'];

}


먼저 처음에 $w = ''를 입력 해서 $w 변수를 초기화 해줍니다.

초기화를 했을 때 아래의 if문의 isset($_POST['w'])가 true라면 comment.php에서 input hidden 태그에 있던 w의 값(w, u, d)를 얻습니다.

만약 w에 값이 없다면 그냥 무시하게 되고 이 경우는 1depth의 댓글을 작성하게 하는거죠.


일단은 아래의 코드들을 더 봐야 하겠지만, isset($_POST['w'])를 통해서 1Depth인지, 2Depth인지, 수정인지, 삭제인지를 구분합니다.


$coNo도 null로 초기화 한 것처럼 보이지만, 사실 null이 아니라 'null'입니다.

뒤에 나올 쿼리에 넣기 위해서 'null'을 적었습니다.

이 $coNo도 1Depth가 아니라면, 즉 isset($_POST['w'])가 TRUE라면 $_POST['co_no']의 값을 받아옵니다.


여기서 $coNo은 2Depth 댓글 쓰기의 경우 해당 상위 댓글(1Depth)의 co_no이 되고,

수정과 삭제의 경우는 수정, 삭제될 댓글의 co_no을 얻습니다.


if($w !== 'd') {//$w 변수가 d일 경우 $coContent와 $coId가 필요 없음.

$coContent = $_POST['coContent'];

if($w !== 'u') {//$w 변수가 u일 경우 $coId가 필요 없음.

$coId = $_POST['coId'];

}

}


이 부분은 공통되지 않는 변수를 출력하는 부분입니다.

만약 $w 변수의 값이 'd'가 아니라면('', w, u) $coContent 변수를 선언하고,

$w 변수의 값이 'u'도 아니라면('', w) $coId 변수를 선언합니다.


if(empty($w) || $w === 'w') { //$w 변수가 비어있거나 w인 경우

$msg = '작성';

$sql = 'insert into comment_free values(null, ' .$bNo . ', ' . $coNo . ', "' . $coContent . '", "' . $coId . '", password("' . $coPassword . '"))';

if(empty($w)) { //$w 변수가 비어있다면,

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


$coNo = $db->insert_id;

$sql = 'update comment_free set co_order = co_no where co_no = ' . $coNo;

}

}


이제 쿼리문을 작성하는 구간입니다.

먼저 empty($w) 혹은 $w === 'w'라면 1Depth 혹은 2Depth의 댓글 쓰기입니다.

이 경우 $msg(메시지) 변수에 '작성'이라는 문구를 넣어주셔야합니다.


그 다음 $sql 변수에 insert 문을 작성합니다.

여기서 중요한 부분은 $coNo인데, 제일 위쪽에서 $w = ''였다면 $coNo = 'null'이고, $w == 'w'라면 $coNo은 1Depth 댓글의 co_id 값이 되는거죠.


그리고 여기서 empty($w)가 TRUE라면(1Depth 댓글 작성이라면) $db->query($sql)로 쿼리를 날리고,

insert 된 데이터의 id 값을 가져온 후 $coNo을 id값과 동일하게 업데이트 해줍니다.


1Depth는 co_id == co_no이여야 하기 때문이죠.

마지막에 $sql변수만 만들고 query를 보내지 않는 이유는 코드의 하단에 공통으로 사용되는 부분이 있기 때문입니다.


else if($w === 'u') { //작성

$msg = '수정';


$sql = 'select count(*) as cnt from comment_free where co_password=password("' . $coPassword . '") and co_no = ' . $coNo;

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

$row = $result->fetch_assoc();


......

}


여기서는 $w === 'u' 일때의 코드가 있습니다.

$w가 'u'라는 것은 수정이라는 뜻이므로 $msg에는 '수정'이라는 문구를 넣어줍니다.


그 다음 $sql 변수를 생성하는데, update문을 작성하기 전에 select 문을 통해서 수정 할 때 입력했던 비밀번호가 저장된 비밀번호와 같은지 확인합니다.

만약 저장된 비밀번호와 같다면 count(*)은 1이 될 것이고 아니면 0이 되겠죠?


if(empty($row['cnt'])) { //맞는 결과가 없을 경우 종료

?>

<script>

alert('비밀번호가 맞지 않습니다.');

history.back();

</script>

<?php 

exit;

}


$sql = 'update comment_free set co_content = "' . $coContent . '" where co_password=password("' . $coPassword . '") and co_no = ' . $coNo;


위에서 얻은 $row['cnt']에 값이 없다면 비밀번호가 맞지 않다는 메시지와 함께 이전 화면으로 돌아갑니다.

값이 있다면 update문을 작성합니다.


여기서도 하단의 공통 query 전송 부분을 사용하므로 따로 query 부분은 없습니다.


else if($w === 'd') { //삭제

$msg = '삭제';

$sql = 'select count(*) as cnt from comment_free where co_password=password("' . $coPassword . '") and co_no = ' . $coNo;


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

$row = $result->fetch_assoc();


if(empty($row['cnt'])) { //맞는 결과가 없을 경우 종료

?>

<script>

alert('비밀번호가 맞지 않습니다.');

history.back();

</script>

<?php

exit;

}

$sql = 'delete from comment_free where co_password=password("' . $coPassword . '") and co_no = ' . $coNo;

}


이번엔 삭제 부분입니다.

$w === 'd'라면 삭제를 나타내므로 $msg에 삭제를 넣어줍니다.


여기서도 역시 select를 이용해서 비밀번호를 확인하고, 결과가 없으면 비밀번호가 맞지 않는다는 알림창을 출력하고 되돌아갑니다.

값이 존재한다면 delete문을 이용해서 삭제 sql을 만들어줍니다.


else {

?>

<script>

alert('정상적인 경로를 이용해주세요.');

history.back();

</script>

<?php 

exit;

}


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


만약 $w의 값이 '', 'w', 'u', 'd' 네 개중에 하나도 일치하지 않는다면 else문이 실행됩니다.

정상적인 경로를 이용했다면 다른 값이 나올 수는 없으므로 정상적인 경로를 이용해달라는 메시지와 함께 이전 화면으로 되돌아갑니다.


만약 모든 if문의 연산이 끝났다면 공통적으로 필요한 query를 전송합니다.


if($result) {

?>

<script>

alert('댓글이 정상적으로 <?php echo $msg?>되었습니다.');

location.replace("./view.php?bno=<?php echo $bNo?>");

</script>

<?php

} else {

?>

<script>

alert('댓글 <?php echo $msg?>에 실패했습니다.');

history.back();

</script>

<?php

exit;

}

?>


if($result) 부분은 기존에 있던 부분이지만 알림창에 나오는 메시지 부분을 보면

"댓글이 정상적으로 <?php echo $msg?> 되었습니다."라는 문구로 바뀌어있습니다.

여기서 $msg 변수에는 작성, 수정, 삭제 중의 하나의 문구가 들어있겠죠?


그 다음 location.replace를 통해서 다시 view 화면으로 되돌아갑니다.

만약 마지막에서 $result값이 없다면 쿼리 전송에 실패 했으니 댓글 (작성, 수정, 삭제)에 실패했다는 문구와 함께 이전 화면으로 돌아갑니다.


여기까지 댓글 작성, 수정, 삭제 부분까지 알아보았습니다.


이번에도 길긴 한데, 오히려 이 부분이 더 쉽다고 느껴지네요.

어려운 부분은 댓글에 남겨주시고, http://kurien.dothome.co.kr에서 현재 진행 상황을 알 수 있습니다.