5. PHP 게시판 만들기, write 제작 2

2015.04.02 23:51
저자 : Kurien

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

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


지금까지 write 입력 폼을 만들었으니, 이제부터는 write에 입력한 값을 업데이트 하는 부분을 만들어 보겠습니다.

파일명은 write_update.php라는 이름으로 만들었습니다.


파일명을 만들때는 파일이 어떤 기능을 하는지를 쉽게 알 수 있는 방법이 좋다고 하기도 하고,

직접 경험해본 결과도 직관적인 이름이 편집하기 더 편했네요.


그럼 먼저 아래의 파일을 다운로드 받아봅시다.


20150402_project.zip


이번에도 다른 부분에 수정사항이 있는데요,

dbconfig.php의 맨 윗부분에 header('Content-Type: text/html; charset=utf-8');이라는 코드를 추가했습니다.


이 부분은 PHP에서의 인코딩을 설정해주는데,

html을 사용한다면 head 태그 내부에 <meta charset='utf-8'>이란 태그를 넣어줌으로써 인코딩을 utf-8로 설정할 수 있지만,

만약 html을 사용하지 않는 이번 페이지(write_update.php) 같은 경우는 인코딩을 설정할 수가 없기 때문에 php에서 설정을 해줍니다.


dbconfig.php에 넣어주는 이유는 모든 페이지에 공통으로 들어가는(include) 부분이기 때문이죠.

만약 일반적인 홈페이지라면 common.php와 같은 모든 페이지에 공통으로 들어가기 위해 만드는 파일에 header와 같은 함수를 설정해줍니다.


서론은 여기까지 하고 write_update.php를 보도록 하죠.


<?php

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


$bID = $_POST['bID'];

$bPassword = $_POST['bPassword'];

$bTitle = $_POST['bTitle'];

$bContent = $_POST['bContent'];

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



$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 . '"))';


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

if($result) { // query가 정상실행 되었다면,

$msg = "정상적으로 글이 등록되었습니다.";

$bNo = $db->insert_id;

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

} else {

$msg = "글을 등록하지 못했습니다.";

?>

<script>

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

history.back();

</script>

<?php

}


?>

<script>

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

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

</script>


전에 만들어놓은 write.php에서 입력 되는 부분은 bID, bPassword, bTitle, bContent 총 네 가지였습니다.

먼저 write_update.php에서도 db를 사용하므로 dbconfig.php를 include 해주시구요,


write.php에서 넘어온 값을 변수에 넣어주는 부분이 있습니다.


write.php의 form 태그에서 method=""속성의 값을 get으로 했다면 $_GET['변수'],

post라고 했다면 $_POST['변수']를 통해서 변수를 얻을 수 있는데요,

만약 $_REQUEST['변수']를 하게되면 get이든, post든 상관없이 모든 값을 받아올 수 있습니다.


그렇다면 $_REQUEST['변수']를 쓰면 편한게 아니냐고 생각하시는 분들이 계실텐데요,

프로그래밍에서는 여러가지의 길이 존재하면 좋은게 아닙니다.

물론 필요할 때 맞춰 쓰는 건 괜찮지만, 될 수 있으면 제작하는 사람이 귀찮은 편이 보안상에는 좋죠.

php의 설정중에는 $_POST['변수']와 같은걸 따로 설정할 필요 없이 $변수로 바로 변경 되게하는 설정이 있는데요,


이렇게 되면 보안적으로는 완전히 떨어지게 되므로 쓰지 않으시는 편이 좋습니다.

물론 현재는 보안적으로는 전혀 신경쓰지 않은 게시판을 만들고 있지만 보안 부분도 다뤄볼 생각입니다.


다시 본론으로 돌아와서 $bID, $bPassword, $bTitle, $bContent라는 변수를 선언했으니 다음 부분을 보겠습니다.

$date라는 변수를 선언 했는데, 여기에는 date('Y-m-d H:i:s')라는 값이 저장됩니다.

이 값은 현재 시간을 나타내주는 함수니까, $date에는 글을 등록한 시간이 저장됩니다.


이제 $sql 변수에 sql문을 작성합니다.

write_update는 글 쓰기를 의미하니 db에는 insert문을 사용해야겠죠?

insert문은 insert into 테이블명 (column 명) values(값);이나, insert into 테이블명 values(값);과 같이 사용되는데요.

저는 더 길게 표현하는 전자를 사용했습니다.


만약 column명을 함께 표현하게 되면 나중에 수정하게 될 때 어떤 부분에 어떤 값이 들어가는지 쉽게 알 수 있거든요.

sql 구문을 만드는 방식은 개인 취향이므로 알아서 하시면 될 것 같네요.


db에서 테이블을 만들 때 primary auto_increment 값을 줬던 column은 값을 입력할 때 null만을 입력해도 자동으로 입력됩니다.

숫자(int) 형식은 0, 10, 23 이런식으로 주변에 감싸는 부분이 없어야 하구요.

문자(char, varchar, date 등) 형식은 ""(큰따옴표)나 ''(작은따옴표)가 있어야합니다.


그리고 또 다른 형식인 password('비밀번호')가 있습니다.

password는 mysql의 자체 함수로 입력받은 문자열을 해시화 해주는데요.


해시라는 것은 원래 불필요한 정보를 모은다는 뜻이 있지만, 암호화에서는 다시 풀어낼 수 없는 암호를 만든다고 생각하시면 됩니다.

만약 kurien이라는 암호를 입력했을 경우에 password() 함수는 *19BA5733867E9DB038840C6FE88CF1007D61E97B라는 해시를 출력합니다.


저 정보를 가지고 다시 풀어낼 방법은 없습니다.

그럼 절대 안뚫리는게 아닌가?라는 생각을 하신 분들에게 말씀 드리자면 저 암호를 다시 kurien이라는 단어로 바꿀 수 있는 방법 자체는 없지만,

password()라는 함수를 누구나 쓸 수 있는 만큼 그 기능을 가지고 각 값을 해시화 해서 데이터베이스에 저장해두고 확인 하는 방법이 존재합니다.

자세한 부분은 나중에 다루도록 하고, 일단은 password() 함수만을 사용해서 하도록 하겠습니다.


이제 insert문을 완성 했으니, $db->query를 통해서 쿼리를 보냅니다.

만약 정상적으로 쿼리가 전달 되었다면 $result에 TRUE가 들어가고, 실패하면 FALSE 값이 들어갑니다.


if문을 이용해서 $result가 정상적으로 동작했다면 $msg에 정상적으로 등록되었다고 적고, $db->insert_id;를 $bNo 변수에 넣어줍니다.

$db->insert_id;는 이번에 insert 된 자료의 auto_increment 값을 다시 반환해주게 되는데,

이 값을 가지고 게시글이 나오는 화면으로 이동 시켜야 하기 때문이죠.


$bNo을 얻었다면, $replaceURL 변수에 './view.php?bno=' . $bNo; 값을 저장합니다.

이 부분은 $bNo(기본 키)를 가지고 게시글을 보여주는 페이지로 이동하기 위한 URL을 저장하는 부분이구요.

view.php는 다음 포스팅에서 다룰 부분입니다.


그 다음 if문을 빠져 나오게 되고 최하단에 있는 <script>alert($msg); location.replace($replaceURL);</script>이 실행됩니다.

성공했다는 메시지와 게시글을 보여줄 페이지로 이동하는 스크립트죠.



만약 위에서 $result에 FALSE가 입력 되었다면 DB 전송이 실패했다는 말이므로 등록에 실패했다는 메시지를 $msg에 저장합니다.

그 다음 <script>alert($msg); history.back();</script>을 통해 $msg를 출력하고, 이전 화면으로 돌아가줍니다.


여기까지 write_update.php 부분이였습니다.

사이사이 주제가 딴대로 새버려서 글이 조금 길어졌지만, 배우면서 필요한 부분이라고 생각되어서 적었던 부분입니다.

어려운 부분이 있다면 질문 부탁드리구요!

잘못된 부분은 거리낌 없이 지적 부탁드립니다!

저작자 표시 비영리 변경 금지
신고
TAG ,
  1. jaenna 2015.04.03 09:09 신고  댓글주소  수정/삭제  댓글쓰기

    잘 보고있어요!!

  2. want 2015.07.09 18:38 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요!! 검색하다가 딱 필요한 정보라 열심히 따라하고있습니다.
    감사합니다.

    but, 질문이 하나있사옵니다..
    잘 따라하고있는데 한글이 DB도 그렇고 출력도 그렇고.. ???? 물음표로 나오는데.. 왜그럴까요??

    • Kurien 2015.07.10 12:47 신고  댓글주소  수정/삭제

      한글이 깨지는 이유는 파일, 서버, DB의 문자가 통일이 안되어있을 때 생기는 현상입니다.

      모든 문자 인코딩을 utf-8로 변경해주세요.

  3. want 2015.07.14 18:13 신고  댓글주소  수정/삭제  댓글쓰기

    댓글 감사드립니다!!
    인코딩 UTF-8로 어찌어찌 하다보니 적용이 되긴되었습니다.
    근데 bin,czech_ci,danich_ci....엄청 많은데 다 의미가 틀린가요?
    검색해서 general_ci 쓰면된다고 해서 했는데

    깊이들어가는거면 그냥 쓰라는거 쓸려구요 ㅋㅋ 갈길이 멀어서...

  4. lee 2015.07.17 11:07 신고  댓글주소  수정/삭제  댓글쓰기

    database connect success Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Tokyo' for '9.0/no DST' instead in C:\workspace\board\write_update.php on line 8 Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given in C:\workspace\board\write_update.php on line 14

    이렇게뜨는데 뭔지모르겟네요 ㅠㅠ

  5. coding 2015.08.02 00:11 신고  댓글주소  수정/삭제  댓글쓰기

    $result = $db->query($sql); 여기서 result라는 변수에 db->query를 넣는다는 것은 알겠는데 그 뒤에는db를 query에 넣는다는 뜻인가요?

    • coding 2015.08.02 00:23 신고  댓글주소  수정/삭제

      만약 $db->query 를 다른 것으로 바꾼다면요 ??
      예를 들어서
      $result = $db->query($sql); 이렇게 쓰면 저같은 경우는
      db에 저장이 안되더라구요 그래서
      mysql_query(sql);로 바꿨더니 되었습니다...

      그럼...$bNo = $db->insert_id;
      이건 어떻게바꿔야 되는건가요?

    • Kurien 2015.08.02 00:28 신고  댓글주소  수정/삭제

      $result = $db->query($sql);에서
      $db는 new mysqli 이라는 코드를 통해서 생성됩니다.
      여기서 new mysqli는 mysqli라는 class를 불러오는 코드고,
      mysqli라는 class 안에 query라는 function이 이미 만들어져 있는겁니다.

      function query($sql) { ... } 이런식으로 되어있겠죠.

      결국 $db->query($sql)은 mysqli라는 class 내부에 있는 query라는 function 을 불러오는 부분입니다.

      객체지향 방식을 배우셨다면 쉽게 이해하실 수 있으실껍니다.

    • Kurien 2015.08.02 00:30 신고  댓글주소  수정/삭제

      $result = $db->query($sql)는 순차지향 방식으로는 $result = mysqli_query($db, $sql)입니다.

      mysql_query($sql)로 됐다면 $db 부분을 mysql_connect()와 같은 함수를 이용해서 만드셨겠네요.
      mysql보다는 mysqli를 쓰시길 권장하구요.

      mysql 방식으로 $bNo = $db->insert_id;는 $bNo = mysql_insert_id();로 알고 있습니다.

  6. 튼튼 2015.10.18 12:40 신고  댓글주소  수정/삭제  댓글쓰기

    감사합니다!

  7. Leakim 2016.02.05 12:28 신고  댓글주소  수정/삭제  댓글쓰기

    안녕 하세요 .kurien님,
    게시판 만드는 방법 쉽게 설명해주셔서 정말 감사하게 보고있어요.

    질문이 있습니다.
    sql문에서 values 값을 입력할때,
    values(null, "' . $bTitle . '", "' . $bContent . '", "' . $date . '", 0, "' . $bID . '", password("' . $bPassword . '"))';

    값을 " ' .$값 . ' " 처럼 큰따옴표/작은따옴표 그리고 '.' 로 감싼 이유가 있을까요?

    • Kurien 2016.02.07 22:47 신고  댓글주소  수정/삭제

      예를 들어서 "' . $bTitle . '" 이 있을 때 $bTitle이 Kurien이라는 단어라고 하면, 이 부분이 mysql로 전달 될 때는 "Kurien" 이라는 문자열이 전달됩니다.
      만약 ' . $bTitle . '이였다면 Kurien이라고 전달이 되지만, 해당 단어는 문자열일 때 사용 되는 큰 따옴표 혹은 작은 따옴표로 감싸져있지 않기 때문에 오류가 출력될 것이구요.

      쉽게 말해서 ""는 mysql에 전달 될 부분이고, ' . . '는 php 상에서 변수를 표현하기 위해서 사용 됩니다.
      다르게 사용하는 방법으로는 "{$bTitle}"도 "' . $bTitle . '"과 같은 결과를 출력합니다.

  8. djpark 2016.03.23 10:52 신고  댓글주소  수정/삭제  댓글쓰기

    설명이 쉽고 상세해서 이해안되는 곳이 없을만큼 좋네요!
    감사합니다.

  9. 시로시로 2016.07.19 13:40 신고  댓글주소  수정/삭제  댓글쓰기

    디비는 연결이 되었는데 디비 안으로 입력한값이 저장이 되질 않네요. ㅜㅜ 글이 등록 되었습니다 라고 알림창이 뜨고나서 다음 view 페이지로 넘어가는데 view창에도 입력한 내용이 나오지 않고 디비에도 저장이 되질 않습니다. 저는 임의로 db부분을 <?php
    header('Content-Type: text/html; charset=utf-8');

    //------------------------디비연결
    $db_ip = "localhost";
    $db_user = "**********";
    $db_pw = "**********";
    $db_name = "************";

    $conn = mysqli_connect($db_ip, $db_user, $db_pw, $db_name);

    if(mysqli_connect_errno($conn)) {
    echo "데이터베이스 연결 실패:" . mysqli_connect_error();
    } else {
    echo "성공!";
    }

    //-------------------------디비연결



    $sql = " select * from board_test ";

    $result = mysqli_query($conn,$sql);


    ?>

    이런식으로 바꿨는데 이부분이 문제인지 궁금합니다..

    아, 객체지향부분을 절차적으로 다 바꿨습니다.

    • Kurien 2016.07.21 21:51 신고  댓글주소  수정/삭제

      남겨주신 내용만으로는 오류가 발생할만한 문제는 없어보이네요.
      kurien92@gmail.com으로 전체 소스 남겨주시면 확인해보고 답변 드릴께요^^

  10. 직딩1 2016.07.26 11:48 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 쭉 잘 보고 있습니다. 질문 하나 남깁니다.

    $bID = $_POST['bID'];
    $bPassword = $_POST['bPassword'];
    $bTitle = $_POST['bTitle'];
    $bContent = $_POST['bContent'];
    $date = date('Y-m-d H:i:s');

    이 부분에서 경고가 뜹니다.

    Do not Access Superglobal $_POST Array Directly.
    Use some filtering functions instead (e.g. filter_input(), conditions with is_*0 functions, etc.).

    정상 등록 알럿창은 뜹니다만... 도움 부탁드립니다. ㅠㅠ

    • 직딩1 2016.07.26 11:50 신고  댓글주소  수정/삭제

      동일 댓글 4개가 연속으로 달렸는데 수정은 되지만 삭제가 안 됩니다... ㅠㅠ

    • Kurien 2016.07.26 12:48 신고  댓글주소  수정/삭제

      일단 삭제 프로그램 부분은 제가 수정할 수 있는 부분이 아니라서 중복된 내용만 지웠구요.

      해당 오류는 저도 처음 보는 오류인데, 아마도 xampp?를 사용했을 때 나오는 오류인 듯 하네요.

      오류 내용으로 봐선 $_POST['변수']처럼 사용하지 말고 filter_input()과 같은 필터링이 가능한 함수를 거쳐 사용하라는 말인 듯 싶습니다.

      http://php.net/manual/kr/function.filter-input.php
      위의 문서를 보고 사용하시면 될 것 같네요.

    • 직딩1 2016.07.26 16:36 신고  댓글주소  수정/삭제

      알려주신 링크대로 했더니 경고가 사라지고 알럿창만 예쁘게 떴습니다. 감사합니다! ^^

  11. 컴공 2016.11.11 17:41 신고  댓글주소  수정/삭제  댓글쓰기

    아니 이렇게 좋고 쉬운글 보고 어렵다느니 외계어라느니..!! 말도안됩니다.

    Kurien 님 정말 감사합니다.

    책 출판하셔도 이것보다 더 쉽게 설명하는 책은 없을 듯 합니다. 진짜 짱..

  12. 감사해요 2017.02.03 15:16 신고  댓글주소  수정/삭제  댓글쓰기

    정말이해가 잘되요.... 짱짱!!!

  13. Hust 2017.02.24 15:26 신고  댓글주소  수정/삭제  댓글쓰기

    처음 공부중이라 필요한부분을 최소한으로 할려고 글 6번까지만 제가 코딩을 했는데요 우선 write.php는 화면에 출력이 잘되고 write_update.php 여기로 넘어가는데 빈화면만뜨네요 그러고 view.php도 마찬가지로 빈화면이떠요 그러고 원래 update되고 view로바로넘어가는거아닌가요? 아직초보여서 힘드네요 답변부탁드립니다

  14. kakoku13 2017.03.17 15:54 신고  댓글주소  수정/삭제  댓글쓰기

    PHP 게시판 만들기, write 제작 1까지 잘 되고 있다가 여기서 막혔답니다ㅠㅠ
    아이디, 비빌번호, 제목,내용을 쓰고 작성을 누르면
    글을 등록하지 못했습니다 라고 팝업창이 뜬답니다. 어디서 부터 잘못됬을까요?

    • Kurien 2017.03.23 09:30 신고  댓글주소  수정/삭제

      제가 올린 코드로는 정상적으로 올라갑니다.
      단순히 안된다고만 말씀하시면 저도 뭐라고 답변해드릴 수가 없어요.
      코드를 올려주신다던지, DB 구조를 살펴보셔야 할 듯 하네요.

  15. TyphoonHacker 2017.04.02 09:12 신고  댓글주소  수정/삭제  댓글쓰기

    아무리 예제 소스라고 하지만 이걸 그대로 사용하시는 사람들이 있을거같은데
    소스가 너무 취약한거같습니다 조금이나마 보안에 관해 언급해주셨으면 하는 ...

    • Kurien 2017.04.03 15:31 신고  댓글주소  수정/삭제

      이 글을 작성할 때 보안에 대한 걱정이 없었어서 그 점을 간과했네요. 빠른 시일 내에 주의하라는 내용 추가하도록 하겠습니다.