11. PHP 게시판 만들기, view 제작 2

2015.04.14 23:49
저자 : Kurien

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

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


오늘은 view 부분의 조회 기능을 만들어보겠습니다.

아래의 파일을 받아주세요.


20150414_project.zip




<?php

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

$bNo = $_GET['bno'];


if(!empty($bNo) && empty($_COOKIE['board_free_' . $bNo])) {

$sql = 'update board_free set b_hit = b_hit + 1 where b_no = ' . $bNo;

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

if(empty($result)) {

?>

<script>

alert('오류가 발생했습니다.');

history.back();

</script>

<?php 

} else {

setcookie('board_free_' . $bNo, TRUE, time() + (60 * 60 * 24), '/');

}

}

$sql = 'select b_title, b_content, b_date, b_hit, b_id from board_free where b_no = ' . $bNo;

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

$row = $result->fetch_assoc();

?>

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8" />

<title>자유게시판 | Kurien's Library</title>

<link rel="stylesheet" href="./css/normalize.css" />

<link rel="stylesheet" href="./css/board.css" />

</head>

<body>

<article class="boardArticle">

<h3>자유게시판 글쓰기</h3>

<div id="boardView">

<h3 id="boardTitle"><?php echo $row['b_title']?></h3>

<div id="boardInfo">

<span id="boardID">작성자: <?php echo $row['b_id']?></span>

<span id="boardDate">작성일: <?php echo $row['b_date']?></span>

<span id="boardHit">조회: <?php echo $row['b_hit']?></span>

</div>

<div id="boardContent"><?php echo $row['b_content']?></div>

<div class="btnSet">

<a href="./write.php?bno=<?php echo $bNo?>">수정</a>

<a href="./delete.php?bno=<?php echo $bNo?>">삭제</a>

<a href="./">목록</a>

</div>

</div>

</article>

</body>

</html>


오늘은 수정한 부분이 적습니다.

기존 view.php 파일에서는 조회수가 올라가지 않았는데요,

이 부분에 대해서만 수정 했습니다.

각 글에 대한 조회수는 b_hit라는 열에 저장되어있습니다.

만약 글을 클릭해서 view.php에 들어온다면 해당 글(b_no)에 대한 b_hit 값을 +1 해주는 sql을 만들고 쿼리를 날려야 합니다.

그런데 여기서 제한이 없이 view.php에 들어올 때마다 b_hit가 늘어난다면 새로고침을 할 때마다 +1이 되는 것을 볼 수 있을겁니다.


여기서 조회수를 제한할 수 있는 세 가지의 방법이 있는데요,

쿠키와 세션, DB를 이용한 방법이 있습니다.


여기서 쿠키를 이용한 방법은 제가 사용했으니 세션과 DB에 대해서 먼저 설명하겠습니다.


세션은 서버에 저장되는 변수라고 생각하시면 되겠습니다.

서버의 한 장소에 데이터를 저장해놓고 필요할 때 찾아서 사용하는 방식이죠.

이런 방식을 사용하는 이유는 기본적인 HTML이나 JavaScript 만을 가지고는 사용자 자신이 누군지 서버에게 알려줄 수가 없기 때문입니다.

세션같은 것이 없다면 로그인을 하더라도 다음 페이지로 넘어가는 순간 풀려버리게 되는거죠.


여기서 세션을 사용하지 않은 이유는 세션은 위에 적었듯이 서버에 저장이 됩니다.

조회수가 프로그램상 정말 중요한 부분이라면 세션이나 DB를 사용해야겠지만,

일반적인 게시판에서는 조회수가 큰 작용을 하지 않기 때문에 쿠키를 이용했습니다.


DB의 경우도 서버에 저장되지만 조회수를 올렸던 사용자가 누구인지 알기 위해서는 ip, 조회수를 올렸던 시간, 글 번호 이 세 가지가 필요합니다.

게다가 계속 DB에 쌓이면 느려지니 삭제도 해줘야 하구요.


쿠키는 위의 두 방법과는 다르게 클라이언트(사용자)의 PC에 저장됩니다.
클라이언트에 저장되는 세션이라고 생각하시면 되겠습니다.


대신 쿠키는 사용자가 맘대로 접근을 할 수 있기 때문에 쿠키를 이용할 때는 보안과는 관련 없는 기능에 사용해야하죠.

그리고 쿠키를 지우게 되면 조회수가 한번 더 오르기 때문에 딱히 하든 안하든 차이가 없는 것 같지만,

조회수 같은 중요하지 않은 기능에 그런 시간을 투자할만한 사람은 적다고 생각됩니다.


이러한 이유로 쿠키를 이용했구요.

이 글을 보시는 분들은 원하는 방법으로 사용하시면 되겠습니다.


if(!empty($bNo) && empty($_COOKIE['board_free_' . $bNo])) {

$sql = 'update board_free set b_hit = b_hit + 1 where b_no = ' . $bNo;

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

if(empty($result)) {

?>

<script>

alert('오류가 발생했습니다.');

history.back();

</script>

<?php 

} else {

setcookie('board_free_' . $bNo, TRUE, time() + (60 * 60 * 24), '/');

}

}


위의 코드를 설명해보자면, 만약 $bNo이 있고, $_COOKIE['board_free_' . $bNo(글 번호)]가 없을 때 update 쿼리를 전송합니다.

결과가 없다면 오류가 발생했다는 메시지를 출력하고 이전 화면으로 돌아갑니다.


결과가 성공이라면 setcookie 함수를 이용해서 'board_free_' . $bNo이라는 쿠키를 만듭니다.

여기서 사용된 setcookie의 매개변수는 setcookie('쿠키 명', '쿠키 값', '쿠키 유지시간', '경로') 순입니다.


쿠키 명은 말 그대로 쿠키를 사용할 때 쓰는 쿠키의 이름으로 배열에서 키 값과 동일한 역할이라고 보시면 되겠구요.

여기서 board_free_$bNo이라는 이름으로 만든 이유는 free라는 이름을 가진 게시판의 글 번호를 나타낸겁니다.


쿠기 값도 배열의 값와 같다고 보시면 되겠습니다.

쿠키 유지시간은 쿠키가 얼마의 시간만큼 유지될 건지를 나타내는 건데요.

time()은 현재 시간을 나타내주고 거기에 + (60(초) * 60(분) * 24(시간))의 값을 더해줍니다.

60 * 60 * 24란 하루를 초로 나타낸 값입니다.

그러므로 하루 후에 다시 조회가 가능하게 되는거죠.


그리고 마지막으로 경로인데 만약 경로부분이 비어있다면 http://kurien.dothome.co.kr/board/에서 글을 조회했을 때는 /board/라는 경로에

쿠키가 생성되고 http://kurien.dothome.co.kr/project/board/에서 글을 조회했을 때는 /board/project/라는 경로에 쿠키가 생성됩니다.


그러므로 한 사람이 2의 조회수를 올릴 수 있게 되는거죠.

이 경로를 /로 고정 함으로써 하루 한번의 조회만 가능하게 했습니다.


여기까지 조회 기능을 만들었는데요.

짧고 간단한 부분인데 설명이 무진장 기네요 ㅠ


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

TAG ,
  1. pooh 2015.04.15 16:11 신고  댓글주소  수정/삭제  댓글쓰기

    글 잘 보고 배우고 있습니다

    $result = $db->query($sql); 에서 -> 는 무슨 의미인가요? 다른 표현으론 어떻게 쓰나요?

    그리고 게시판에 이미지도 같이 보이는거도 혹시 강좌 하시나요? 버튼하나 누르면 여러개 고를수 있는..

    앞으로도 꾸준히 보면서 도움 받겠습니다

    좋은하루되세요

    • Kurien 2015.04.15 18:42 신고  댓글주소  수정/삭제

      게시판을 만드시기 전에 php와 mysql을 공부하셔야합니다.
      기초가 중요하기 때문에 기초가 부족하시면 게시판 만드는 것 자체를 이해하기 힘드실겁니다.

      http://blog.kurien.co.kr/345 이 링크는 php와 mysql 연동에 관한 부분입니다.
      적어도 이 부분은 보시는게 빠를 것 같습니다.

      그리고 게시판에 이미지도 같이 보이는게 어떤걸 말씀하시는지 잘 모르겠습니다;

  2. slot89 2015.06.04 15:29 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. 게시판 만드는 법에 대해 공부중입니다.
    다름이 아니라 소스를 받아서 천천히 이해해가며 실행해보고 있는데요
    자잘한 Warning들이 많이 나와서 수정해가고 있는데 이부분은 도저히 수정이 안되네요..

    Warning: Cannot modify header information - headers already sent by (output started at /web/home/slot89/html/dbconfig.php:1) in /web/home/slot89/html/board/view.php on line 16

    16번째 줄이면 setcookie 부분입니다. 인코딩 문제와 ob_start();도 적용해보았는데 사라지질 않네요..
    혹시 해결방법을 여쭤봐도 될까요?

    페이지는 제 아이디에 링크걸어두었습니다..

    • Kurien 2015.06.04 21:38 신고  댓글주소  수정/삭제

      /board/view.php의 16번째 줄 부분이 header보다 먼저 나와서 인 것 같은데,
      setcookie를 header 부분 뒤로 빼보세요.
      원래 header가 나오기 전에 뭔가가 출력되거나, cookie 관련된 내용이 존재하면 저런 오류를 내보냅니다.

  3. won 2015.07.23 00:36 신고  댓글주소  수정/삭제  댓글쓰기

    게시판 만들기 잘 보고있습니다. 그런데 한가지 잘 구현이 안되는 점이 있어 질문드립니다.
    현재 게시판에서 글 조회를 하면 조회수는 정상적으로 올라가고, 한번씩만 올라가는 것도 잘 됩니다.
    그런데 현재 조회수가 올라갈 때마다 b_date가 조회를 하는 그 시각으로 변경이 되어버립니다. 분명히 어디에도 b_date를 업데이트 시키는 코드가 없는데 계속 이런 현상이 발생해서 답답하네요. 뭐가 문제인지 감이 잡히지 않아 여쭤봅니다.

    • Kurien 2015.07.23 09:14 신고  댓글주소  수정/삭제

      won님께서 수정하신 코드를 kurien92@gmail.com으로 보내주세요.
      확인해볼께요.

    • 신기루 2015.11.11 15:08 신고  댓글주소  수정/삭제

      게시판에서 글 조회를 하는데 date 값도 업데이트가 된다는 소린데..
      업데이트 구문에 b_date가 업데이트 되도록 되어 있는거 아닌가요?
      분명히 어디에도 b_date를 업데이트 시키는 코드가 없는데
      저런 현상이 발생하진 않을 거에요.

  4. bigstar131 2016.06.25 23:25 신고  댓글주소  수정/삭제  댓글쓰기

    검색 값을 팝업으로 띄울려면 어떻게 해야 하나요?

    • Kurien 2016.06.27 09:58 신고  댓글주소  수정/삭제

      "검색 결과를 팝업에 표시하는 방법"이라고 이해 하고 답변 드리겠습니다.
      javascript를 이용해서 검색 버튼을 눌렀을 때 open() 함수를 통해 팝업을 생성합니다.
      이 때 open() 함수에서 url 경로는 list와 비슷하게 제작된(검색 결과 list) 프로그램이여야 합니다.

      그리고 해당 open() 값을 변수로 받아서 해당 팝업으로 submit 이벤트를 보내면 될 것 같습니다.

  5. bigstar131 2016.07.01 18:59 신고  댓글주소  수정/삭제  댓글쓰기

    해드에 자바스크립트 넣고 버튼에는 onclik을 넣어서 연결시켜 실행되도록 했는데요..
    검색 버튼을 2번 눌러야 값이 팝업창으로 넘어가네요..

    제가 자바를 배우지 않아서.. 아래 소스중 어느 부분을 고쳐야 할까요?

    function rank_search_pop() {
    var pop_suburl = <?php echo json_encode($subString) ?>;
    var pop_main = "./index_popup.php?"+pop_suburl;
    window.open(pop_main, "_bank", "width=400,height=300,resizable=1,scrollbars=1");
    }
    </script>

    <button onClick="rank_search_pop();">검색</button>

    • Kurien 2016.07.02 01:49 신고  댓글주소  수정/삭제

      코드 일부분만 봐서는 저도 알 수 없습니다.
      $subString이 무슨 변수인지를 알 수가 없고, form이 어떻게 되어있는지도 모르구요.
      kurien92@gmail.com으로 해당 전체 코드를 보내주시면 확인 후 답변 드리겠습니다.

  6. bigstar131 2016.07.02 14:07 신고  댓글주소  수정/삭제  댓글쓰기

    보냈습니다

  7. 직딩1 2016.08.02 11:14 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요.
    에러 하나를 잡으니 또 다른 에러가 뜨네요... ㅎㅎ...

    $row=$result->fetch_assoc(); 에서 에러가 나는 바람에 if문으로 감싸줬습니다.

    if(isset($no)){
    $sql='select b_title, b_content, b_date, b_hit, b_id from board where b_no='.$no;
    $result=$db->query($sql);
    $row=$result->fetch_assoc();
    }

    그랬더니 이런 에러가 뜨네요.

    Notice: Undefined variable: row in 경로

    해당 에러는 html에서 데이터 가져오는 부분... 그러니까 $row가 쓰인 부분에서 동일하게 일어납니다.
    검색해보니 $row가 정의되지 않았다는데 어떻게 해야 할까요 ㅠㅠ
    조회수가 올라가지 않는 것도 이렇게 에러가 떠서 일까요...

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

      게시글이 view를 다루는 부분이니 view라고 생ㅇ각한다면, $no이 없는 경우엔 글이 안보이는게 정상입니다.

      그런데 오류난다고 하시는 부분을 보면 전부 $no이 없는 경우 나타날만한 오류네요.

      그리고 나타난 오류와 조회수는 관계 없어보입니다.

      다시 확인 해보신 후 댓글 부탁드릴께요.

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

      안녕하세요. 답변 감사합니다.

      말씀하신 $no가 없는 경우라면 데이터가 없는 경우라고 생각하면 될까요?
      list에는 이미 3개의 데이터가 존재하고 list의 게시글 제목을 클릭해 이동해봐도 같은 에러가 뜹니다.

      혹시나 싶어서 cmd 창에서 selete로 조회했지만 b_no에 데이터가 잘 들어가 있구요.

      게시글을 클릭했을 때 넘어간 페이지의 주소창에는 ~no=1도 잘 나오고...

      혹시 다른 원인이 있을 수 있을까요?
      참고로 xampp 설치했습니다...

      도움 부탁드려요 ㅠㅠ

    • Kurien 2016.08.03 16:44 신고  댓글주소  수정/삭제

      no=1이라고 나오신다고 하셨는데요.
      $no = $_GET['no'];같은 코드가 존재하는지 확인 부탁드릴께요.

    • 직딩1 2016.08.03 17:38 신고  댓글주소  수정/삭제

      빠른 답변 감사합니다.

      말씀하신 부분은 제가 xampp를 써서 그런지 예전에 에러가 났던 부분입니다. 아마 write_update 부분에서 제가 질문을 드린 적이 있을 거예요... 그 때 알려주신 filter_input으로 에러 해결을 했었구요.

      그래서 view에서도 그렇게 썼었는데... get으로 해야 되는데 post를 썼었네요 ;; 수정하니까 그 에러들은 사라졌습니다!

      정말 감사합니다. 이틀이나 붙잡고 있었는데 한큐에 해결됐어요 ㅎㅎ

      그런데 조회수는 왜 이렇게 잘 올라갈까요... 새로고침 할 때마다 +1이 되네요 ㅠㅠ

    • Kurien 2016.08.03 23:00 신고  댓글주소  수정/삭제

      setcookie('board_free_' . $bNo, TRUE, time() + (60 * 60 * 24), '/');
      이부분이 빠지진 않으신건지, 수정하신 코드에 맞게 변경되어있는지 확인해보세요.

  8. dahun 2016.08.29 11:39 신고  댓글주소  수정/삭제  댓글쓰기

    조회수가 1밖에 올라가지 않는데 어떤 부분을 봐야하나요...? $bNo 값도 잘 받아지는데 어떤 문제인지 예측이 안되네요..ㅎ

    <?php
    require_once("../dbconfig.php");
    $bNo = $_GET['bno'];

    if(!empty($bNo) && empty($_COOKIE['board_free_' . $bNo])) {
    $sql = 'update board_free set b_hit = b_hit + 1 where b_no = ' . $bNo;
    $result = $db->query($sql);
    if(empty($result)) {
    ?>
    <script>
    alert('오류가 발생했습니다.');
    history.back();
    </script>
    <?php
    } else {
    setcookie('board_free_' . $bNo, TRUE, time() + (60 * 60 * 24), '/');
    }
    }

    $sql = 'select b_title, b_content, b_date, b_hit, b_id from board_free where b_no = ' . $bNo;
    $result = $db->query($sql);
    $row = $result->fetch_assoc();
    ?>

    • Kurien 2016.09.06 17:23 신고  댓글주소  수정/삭제

      setcookie('board_free_' . $bNo, TRUE, time() + (60 * 60 * 24), '/');
      위의 코드가 조회수를 1만 올라가게 하는 코드입니다.

      조회수가 계속 올라간다면 새로고침 될 때마다 조회수가 상승되기 때문에 하루에 한번만 올라가게 제작되어있는 것입니다.

  9. 안녕하세요 2017.07.18 00:39 신고  댓글주소  수정/삭제  댓글쓰기

    쿠키 세션으로 안들어가집니다...
    <?php
    require_once("dbconfig.php");

    $bNo = $_GET['bno'];
    echo "'bNo123 : ' $bNo ";
    // 만약 $bNo이 있고, $_COOKIE['board_free_' . $bNo(글 번호)]가 없을 때 update 쿼리를 전송
    if(!empty($bNo) && empty($_COOKIE['board_free_' . $bNo])) {
    echo "'bNo2 : ' $bNo ";
    $sql = 'update board_free set b_hit = b_hit + 1 where b_no = ' . $bNo;
    $result = $db->query($sql);
    if(empty($result)) {
    ?>
    <script>
    alert('오류가 발생했습니다.');
    history.back();
    </script>
    <?php
    } else {
    setcookie('board_free_' . $bNo, TRUE, time() + (60 * 60 * 24), '/');
    }
    } else {
    echo "<br><br>'안들어가짐'";
    }

    이렇게 해놨더니 bNo의 값도 echo로 나오고 안들어가짐도 echo로 나오네요 뭐가 문제일까요?