PHP-board

이강민·2022년 2월 9일

PHP & MySQL&Ajax&node

목록 보기
8/16
post-thumbnail

PHP-board

지금까지 배운 php와 sql, 그리고 Ajax, js를 이용하여 게시판을 만들 것이다.
먼저 기본적인 구상은 다음과 같다.

회원가입 회원가입 검증 회원 정보 데이터화 로그인 로그인 검증 회원게시판 게시판 글쓰기 글 조회하기 수정하기 삭제하기 좋아요 누르기

여기서 css를 사용하지 않았으며 표를 만들기 위한 기본적인 style만 적용시켰다.

regist.php

  • post 방식의 전달 방식, sendit() 함수를 통한 유효성 검사
  • checkid() 함수를 통한 중복확인 검사
  • hobby[] 전달을 통한 배열 데이터 관리
  • 외부 주소 api를 활용한 주소찾기
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>회원 가입</title>
  <script src="./js/regist.js"></script>
</head>
<body>
  <h2>회원가입</h2>
<!-- 회원 가입을 위한 form, post방식, 제출 시 sendit()함수 실행하여 유효성 검사를 겸한다. -->
  <form action="regist_ok.php" method="post" name="regform" id="regform" onsubmit="return sendit()">
    <!-- 중복 또는 사용가능 여부 글자를 넣어줄 것이다. -->
  <p id="result" >&nbsp;</p>
    <p>
      <label>아이디 : <input type="text" name="userid" id="userid" maxlength="20"></label>
      <!-- 중복확인을 누르면 checkid함수를 실행하여 중복 검사를 한다. -->
      <input type="button" value="중복확인" onclick="checkId()">
    </p>
    <p><label>비밀번호 : <input type="password" name="userpw" id="userpw" maxlength="20"></label></p>
        <p><label>비밀번호 확인 : <input type="password" name="userpw_re" id="userpw_re" maxlength="20"></label></p>
        <p><label>이름 : <input type="text" name="name" id="username"></label></p>
        <p><label>휴대폰 번호 : <input type="text" name="hp" id="hp"></label></p>
        <p>
            <label><input type="radio" name="usergender" value="남자" checked></label>
            <label><input type="radio" name="usergender" value="여자"></label>
        </p>
        <p><label>이메일 : <input type="text" name="email" id="email"></label></p>
        <p>취미
          <!--  php로 여러 데이터를 전달 받을때는 name="배열명[]" 으로 작성한다.-->
            <label>드라이브<input type="checkbox" name="hobby[]" value="드라이브"></label>
            <label>영화감상<input type="checkbox" name="hobby[]" value="영화감상"></label>
            <label>공부<input type="checkbox" name="hobby[]" value="공부"></label> 
            <label>게임<input type="checkbox" name="hobby[]" value="게임"></label> 
            <label>운동<input type="checkbox" name="hobby[]" value="운동"></label>
            <label>코딩<input type="checkbox" name="hobby[]" value="코딩"></label>
        </p>
        <p>
          <!-- 외부 api로 주소찾기를 사용하였다.  -->
            <input type="text" id="sample6_postcode" placeholder="우편번호" name="zipcode" readonly>
            <input type="button" onclick="sample6_execDaumPostcode()" value="우편번호 찾기">
        </p>
        <p>
            <input type="text" id="sample6_address" placeholder="주소" name="address1" readonly>
            <input type="text" id="sample6_detailAddress" placeholder="상세주소" name="address2"><br>
            <input type="text" id="sample6_extraAddress" placeholder="참고항목" name="address3" readonly>
        </p>
        <p><input type="submit" value="가입완료"> <input type="reset" value="다시작성"></p>
  </form>
</body>
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
    function sample6_execDaumPostcode() {
        new daum.Postcode({
            oncomplete: function(data) {
                // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                // 각 주소의 노출 규칙에 따라 주소를 조합한다.
                // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                var addr = ''; // 주소 변수
                var extraAddr = ''; // 참고항목 변수

                //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
                if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
                    addr = data.roadAddress;
                } else { // 사용자가 지번 주소를 선택했을 경우(J)
                    addr = data.jibunAddress;
                }

                // 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
                if(data.userSelectedType === 'R'){
                    // 법정동명이 있을 경우 추가한다. (법정리는 제외)
                    // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
                    if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
                        extraAddr += data.bname;
                    }
                    // 건물명이 있고, 공동주택일 경우 추가한다.
                    if(data.buildingName !== '' && data.apartment === 'Y'){
                        extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                    }
                    // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
                    if(extraAddr !== ''){
                        extraAddr = ' (' + extraAddr + ')';
                    }
                    // 조합된 참고항목을 해당 필드에 넣는다.
                    document.getElementById("sample6_extraAddress").value = extraAddr;
                
                } else {
                    document.getElementById("sample6_extraAddress").value = '';
                }

                // 우편번호와 주소 정보를 해당 필드에 넣는다.
                document.getElementById('sample6_postcode').value = data.zonecode;
                document.getElementById("sample6_address").value = addr;
                // 커서를 상세주소 필드로 이동한다.
                document.getElementById("sample6_detailAddress").focus();
            }
        }).open();
    }
</script>
</html>

regist.js

  • sendit() 함수 정의
  • checkId() 함수 정의 및 xmlhttprequest를 통한 데이터 가져오기
  • get 방식으로 checkId_ok.php에 전달
// 아이디를 유효성 검사하는 함수를 만들 것이다.
const sendit = function () {
  // 본 함수는 regist내에서 실행되기 때문에 form의 name인 regform을 가져올 수 있으며, form이 가지고 있는 userid 또한 사용가능하다.
  const userid = document.getElementById("userid");
  const result = document.getElementById('result');
  // 아이디를 입력하지 않았을때 
  if(userid.value == ''){
    alert("아이디를 입력하세요!");
    userid.focus();
    return false;
  }
  // 아이디를 만들 조건제약
  if(userid.value.length < 5 || userid.value.length > 12){
    alert("아이디는 5자 이상 12자 이하로 입력하세요!");
    userid.focus();
    return false;
  }
  // result가 &nbsp일 경우 중복체크 경고 띄우기
  if(result.innerHTML == "&nbsp;"){
    alert("아이디 중복체크를 진행해주세요!");
    return false;
  }
  // 중복된 아이디 일 경우, 주의 문자열로 조건식을 만들때는 공백과 띄우쓰기까지 동일해야 함으로 추천하지 않음
  if(result.innerHTML != "사용할 수 있는 아이디입니다."){
    alert("중복된 아이디입니다! 다시 중복체크를 해주세요!");
    return false;
  }
  // password도 위와 동일
  const userpw = document.regform.userpw;
    const userpw_re = document.regform.userpw_re;
    if(userpw.value == ''){
        alert("비밀번호를 입력하세요!");
        userpw.focus();
        return false;
    }
    if(userpw.value.length < 6 || userpw.value.length > 20){
        alert("비밀번호는 6자 이상 20자 이하로 입력하세요!");
        userpw.focus();
        return false;
    }
    if(userpw_re.value == ''){
        alert("비밀번호 확인을 해주세요!");
        userpw_re.focus();
        return false;
    }
    // 입력한 패스워드와 패스워드 확인이 동일하지 않으면 다시 입력 받는다.
    if(userpw.value != userpw_re.value){
        alert("비밀번호와 비밀번호 확인이 일치하지 않습니다!");
        userpw.focus();
        return false;
    }
    // 이름의 유효성 검사
    const name = document.getElementById('username');
    // 정규식을 검사할때 검색한 조건.test(확인하고자 하는 값)으로 비교한다.
    //정규식, 가 - 힣은 모든 한글을 검색한다.
    const expNameText = /[가-힣]+$/;
    if(!expNameText.test(name.value)){
        alert("이름 형식을 확인하세요! 한글만 입력하세요!");
        name.focus();
        return false;
    }
    // 휴대폰 번호, email 검사 위와 동일
    const hp = document.getElementById("hp");
    const expHpText = /^\d{3}-\d{3,4}-\d{4}$/;
    if(!expHpText.test(hp.value)){
        alert("휴대폰번호 형식을 확인하세요!");
        hp.focus()
        return false;
    }
    const email = document.regform.email;
    const expEmailText = /^[A-Za-z0-9\.\-]+@[A-Za-z0-9\.\-]+\.[A-Za-z0-9\.\-]+$/
    if(!expEmailText.test(email.value)){
        alert("이메일 형식을 확인하세요!");
        email.focus();
        return false;
    }
    
    const hobbies = document.regform.hobby;
    let flag = false;
    // 체크된 취미 목록을 가져온다.
    for(let i=0; i<hobbies.length;i++){
      if(hobbies[i].checked){
        flag = true;
        break;
      }
    }
    // 하나도 체크가 안되어있으면 flag는 false이다.
    if(!flag){
      alert("취미는 적어도 1개이상 선택하세요!");
      return false;
    }
    const zipcode = document.regform.zipcode;
    if(zipcode.value == ''){
        alert("주소를 입력하세요!");
        sample6_execDaumPostcode();
        return false;
    }
    const address2 = document.regform.address2;
    if(address2.value == ''){
        alert("상세주소를 입력하세요!")
        address2.focus();
        return false;
    }
    return true;
    
}

// 중복검사를 위한 함수를 만든다.
function checkId(){
  // 가져올 id와 값을 넣을 result를 선택한다.
  const userid = document.getElementById("userid");
  const result = document.getElementById("result");

  // 중복검사를 하더라도 유효성도 같이 하는 것이 좋다.
  if(userid.value == ''){
    alert("아이디를 입력하세요!");
    userid.focus();
    return false;
  }
  if(userid.value.length < 5 || userid.value.length > 12){
      alert("아이디는 5자 이상 12자 이하로 입력하세요!");
      userid.focus();
      return false;
  }

  // Ajax로 값을 가져와서 중복확인 결과를 띄어주자
  // Ajax 사용 준비
  const xhr = new XMLHttpRequest();
  // readystate가 변화될때마다 실행
  xhr.onreadystatechange = function(){
    if(xhr.readyState == XMLHttpRequest.DONE){
      if(xhr.status == 200){
        // 요청하고 받은 값을 문자로 받고 trim으로 공백을 제거한다.
        let txt = xhr.responseText.trim();
        console.log(xhr.responseText)
        if(txt == "O"){
          // result에 해당 문구를 적음
          result.innerHTML = "사용할 수 있는 아이디 입니다."
        }else{
          result.innerHTML = "중복된 아이디 입니다."
        }
      }
    }
  }
  // Ajax를 사용하려면 open과 send함수를 사용한다.
  // 이때 해당 php에 get방식으로 요청이 된다. 
  xhr.open("GET", "checkId_ok.php?userid="+userid.value, true);
  xhr.send();
}

dbconn.php

  • 자주쓰는 sql 문 만들어 놓기
<?php
  $conn = mysqli_connect("127.0.0.1", "root", "***", "frontend") or die("데이터 연결실패");
?>

chekId_ok.php

  • Ajax로 요청한 데이터를 sql문으로 받아오기
<?php
//자주쓰는 sql문 걸어놓기(데이터베이스 연결)
  include "./include/dbconn.php";
  //xml에서 요청 받은 get방식의 userid 변수에 담기
  $userid = $_GET['userid'];

//sql 변수에 userid 찾아서 idx로 가져오기 
  $sql = "select useridx from tb_user where userid = '$userid'";
//데이터베이스에 연결해서 $sql 실행 후 result 변수에 담기
  $result = mysqli_query($conn, $sql);
  // 담기 변수를 배열로 받아오기
  $data = mysqli_fetch_array($result);
//useridx가 있으면 X 없으면 O로 echo 하기
  echo isset($data['useridx']) ? "X" : "O";
?>

regist_ok.php

  • 회원가입하면서 post 방식으로 받아온 데이터 변수에 넣기
  • 배열로 받은 데이터 처리하여 담기
  • sql 문을 실행하여 데이터베이스 테이블에 회원정보 저장하기
<?php
    include "./include/dbconn.php";
    $userid = $_POST['userid']; 
    $userpw = $_POST['userpw'];
    $username = $_POST['name'];
    $userphone = $_POST['hp'];
    $usergender = $_POST['usergender'];
    $useremail = $_POST['email'];
    $userhobby = $_POST['hobby'];   //['공부','게임','코딩']
    $hobbystr = $userhobby[0];      //"공부"
    
    for ($i=1; $i < count($userhobby); $i++) {      //1 2
        $hobbystr .= ",".$userhobby[$i];    //"공부,게임,코딩"
    }
    $zipcode = $_POST['zipcode'];
    $address1 = $_POST['address1'];
    $address2 = $_POST['address2'];
    $address3 = $_POST['address3'];
    // 여기까지 회원가입으로 post 방식으로 받아온 데이터들을 변수로 저장하였다.

    // sql문변수에 실행문을 담아 놓는다., 사용자 정보를 담기위해 insert 한다. (기타 설명은 mysql 참고)
    $sql = "insert into tb_user (userid,userpw,username,userphone,useremail,userhobby,zipcode,address1,address2,address3,usergender) values('$userid',md5('$userpw'),'$username','$userphone','$useremail','$hobbystr','$zipcode','$address1','$address2','$address3','$usergender')";
    
    // 데이터를 연결하여 sql문을 실행한다.
    $result = mysqli_query($conn,$sql);
    //insert into 테이블명 values (apple,10,...)
    // 쿠키에 저장하여 추후 사용한다.
    setcookie("joinid",$userid,time()+60*5,"/");
?>
<script>
  // 회원가입 성공 알람 창과 login.php로 보낸다.
    alert("회원가입 성공!");
    location.href="./login.php";
</script>

login.php

  • 저장된 쿠키 사용하기
  • 저장된 세션 가져와서 로그인 여부 확인하기
<!-- 로그인 php -->
<!-- 세션을 사용할 것이며 login_ok에서 처리되는 세션을 이용할 것이다 -->
<?php session_start();?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>로그인</title>
</head>
<body>
  <?php
  // regist_ok.php가 정상 작동되면 setcookie 되어 joinid라는 이름의 'userid'가 쿠키에 저장된다.
    $joinid = '';
    // userid쿠키가 존재하면 joinid변수에 userid를 넣는다.
    if(isset($_COOKIE['userid'])){
      $joinid = $_COOKIE['userid'];
    }
  ?>
  <!-- 세션이 없다면 로그인이 안되어 있다는 것으로 로그인 창에 있어야 되고 세션에 값이 존재하면 login_ok창을 보여준다. -->
  <?php
    if(!isset($_SESSION['userid'])){
  ?>
    <h2>로그인</h2>
    <form action="login_ok.php" method="post">
      <p>아이디 : <input type="text" name="userid" value = "<?=$joinid?>"></p>
      <p>비밀번호 : <input type="password" name="userpw" ></p>
      <p><input type="submit" value="로그인"></p>
    </form>
    <a href="./regist.php">회원가입</a>
  <?php
    }else{
  ?>
      <p><?=$_SESSION['userid']?>님 환영합니다</p>
      <p>
        <a href="./logout.php">로그아웃</a> | 
        <a href="#">회원게시판</a>
      </p>
  <?php
    }
  ?>
  
</body>
</html>

login_ok.php

  • 세션 사용,
  • post로 전달 받은 데이터로 데이터베이스를 검색하여 결과 돌려주기
  • flag처리하여 로그인 여부 판단
<!-- 로그인 성공 시 php 처리 -->
<?php
  // 세션 사용
  session_start();
  // 데이터베이스 연결 include
  include "./include/dbconn.php";
  // post로 받은 userid와 userpw를 가져온다.
  $userid = $_POST['userid'];
  $userpw = $_POST['userpw'];
  // sql 실행 문에 userid 와 userpw를 찾는 실행문을 담는다.
  $sql = "select useridx, userid, username from tb_user where userid= '$userid' and userpw=md5('$userpw')";
  $result = mysqli_query($conn, $sql);
  // db에 로그인 정보를 이용하여 검색하고 data에 담는다.
  $data = mysqli_fetch_array($result);

  // userid 검색결과가 있으면 userid를 없다면 공백을 반환한다.
  $flag = isset($data['userid']) ? $userid : '';
  if($flag !=''){
    // 공백이 아니라면(값이 있다면) 세션에 다음과 같이 담는다.
    $_SESSION['userid'] = $userid;
    $_SESSION['useridx'] = $data['useridx'];
    $_SESSION['username'] = $data['username'];
    // 로그인 성공 창을 띄우고 login.php로 돌아간다.(이제 세션이 존재하여 다른 뷰단을 만들 것이다.)
    echo "<script>alert('로그인 성공'); location.href='./login.php';</script>";
  }
  else{
    // 실패시 처리,
    echo "<script>alert('로그인 실패, 다시 로그인 해주세요.');";
    // 돌아가기
    echo "history.back(); </script>";
  }
?>

logout.php

  • 세션으로 관리되는 로그인, 세션제거해서 로그아웃 시키기
<?php
  session_start();
  // 세션을 만료시켜 로그아웃 시킨다.
  session_unset();
?>
<script>
  alert("안녕히가세요....☆");
  location.href="./login.php";
</script>

list.php

  • 저장된 데이터 가져오기
  • page 넘겨서 많은 데이터 보기(1페이지당 10개씩)
  • while문 사용해서 게시판 데이터 가져오기
  • 반복문 사용하여 데이터 갯수만큼 pagenum 만들기
<!-- 전체 글 갯수 가져오기, 페이지마다 보여줄 글의 갯수 결정하기 -->
<?php
  include "../include/dbconn.php";
  include "../include/logincheck.php";
  // 전체 테이블 갯수 가져오기
  $sql = "select count(boardidx) total from tb_board";
  $result = mysqli_query($conn, $sql);
  $data = mysqli_fetch_array($result);

  $total = $data['total'];
  
  $pageCount = 10; //페이지 당 보여줄 갯수
  $start = 0; // 게시글의 시작 행 번호
  $page = 1; //페이지 번호 지정하지 않으면 1

  // list.php?page=pagenum; 으로 받아올 것이다.
  if(isset($_GET['page'])){
    $page = $_GET['page'];            // 4 
    $start = ($page - 1) * $pageCount; // (4-1) * 10 = 30, 4페이지는 30부터 39까지이다.
  }
  // start와 page를 재할당 하였으니 해당되는 페이지를 가져오자(데이터 베이스 테이블은 사전에 생성)
  $sql = "select boardidx, boardtitle, userid, boardhit, boardlike, boardregdate from tb_board order by boardidx desc limit $start, $pageCount"; 
  $result = mysqli_query($conn, $sql);
?>

<!-- 게시판  -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>리스트</title>
</head>
<body>
  <h2>리스트</h2>
  <table border="1" width="800">
    <tr>
      <th>번호</th>
      <th>제목</th>
      <th>글쓴이</th>
      <th>조회수</th>
      <th>좋아요</th>
      <th>날짜</th>
    </tr>
    <!-- 테이블의 데이터가 받아올때마다 반복적으로 생성해야한다. -->
    <!-- data를 배열로 받아와 배열이 끝날때까지 반복시키면 된다. -->
    <?php
      while($data = mysqli_fetch_array($result)){
        $boardidx = $data['boardidx'];
        $boardtitle = $data['boardtitle'];
        $userid = $data['userid'];
        $boardhit = $data['boardhit'];
        $boardlike = $data['boardlike'];
        $boardregdate = $data['boardregdate'];
    ?>
      <tr>
        <!-- 무엇으로 글의 정보를 구분할 것인가??, 글마다 보유하고 있는 boardidx로 구분 하는 방법이 있다. -->
        <td><?=$boardidx?></td>
        <!-- 페이지를 누르면 이동할때는 boardidx를 넘겨야 해당 페이지의 데이터레이블을 가져와 뷰단을 만들 수 있다. -->
        <td><a href="./detail.php?boardidx=<?=$boardidx?>"><?=$boardtitle?></a></td>
        <td><?=$userid?></td>
        <td><?=$boardhit?></td>
        <td><?=$boardlike?></td>
        <td><?=$boardregdate?></td>      
      </tr>
    <?php
      }
    ?>
    <!-- 페이지 넘기는 pagenum 만들기 -->
    <tr>
      <td colspan="6" align="center">
        <?php
        // 마지막 페이지를 알고 마지막 페이지 만큼 반복시켜 i를 출력한다.
          $endPage = ceil($total/$pageCount);
          // 마지막 증감연산자 뒤에는 ;를 붙이지 않는다.
          for($i=1; $i<$endPage; $i++){
            // page와 i가 동일하면 a태그 없이 i를 붙이고
            if($page == $i){
              echo "[".$i."]";
            }else{
              //그 외 a태그로 i를 붙인다.
              echo "<a href ='./list.php?page=$i'>[$i]</a>";
            }
          }
        ?>
      </td>
    </tr>
  </table>
    <!-- 글쓰기 버튼을 추가한다. -->
  <p><a href="./write.php">글쓰기</a></p>
</body>
</html>

detail.php

  • 해당 게시판 글 눌러서 자세히 보기
  • 데이터베이스에서 데이터를 가져오고 조회수 부분을 update로 증가시켰다.
  • 세션에서 가지고 있는 로그인 정보와 가져온 게시글의 유저 정보를 비교하여 수정, 삭제 버튼과 좋아요 버튼을 활성화 시켰다.
  • 댓글 데이터베이스도 가져와서 작성된 댓글창도 만듦
  • like함수를 만들어 like_ok.php와 통신하게 만들었다.
<!-- get방식으로 boardidx를 가져와서 해당 데이터테이블을 요청해서 받아와야한다. -->
<?php
  include "../include/logincheck.php";
  include "../include/dbconn.php";

  // get방식으로 가져온 데이터가 없으면 돌려보냄
  if(!isset($_GET['boardidx'])){
    echo "<script>alert('데이터가 없수 돌아가슈'); location.href = './list.php';</script>";
  }
  //get방식으로 데이터를 가져옴
  $boardidx = $_GET['boardidx'];
  // boardidx가 유효하지 않은 번호를 유효성 검사로 막아주어야 한다.
  $sql = "select boardidx from tb_board where boardidx = $boardidx";
  $result = mysqli_query($conn, $sql);
  $data = mysqli_fetch_array($result);
  // 데이터베이스에서 검색한 결과가 없다면 돌려보냄
  if(!isset($data['boardidx'])){
    echo "<script>alert('데이터가 없수 돌아가슈'); location.href = './list.php';</script>";
  }
  // 데이터가 있고 데이터를 볼 수 있다면 조회수를 올릴 수 있다. 여기서는 본인의 글의 조회수를 막는 작업을 하지 않는다.
  $sql = "update tb_board set boardhit = boardhit + 1 where boardidx = $boardidx";
  $result = mysqli_query($conn, $sql);
  
  // 이제 게시글의 내용을 가져오자 
  $sql = "select * from tb_board where boardidx = $boardidx";
  $result = mysqli_query($conn, $sql);
  $data = mysqli_fetch_array($result);

  $boardidx = $data['boardidx'];
  $boardtitle = $data['boardtitle'];
  $boardcontent = $data['boardcontent'];
  $boardlike = $data['boardlike'];
  $boardhit = $data['boardhit'];
  // 글을 작성한 사용자가 아닌 기존에 글을 쓴 사용자의 id가 담긴다.
  $userid = $data['userid'];
  $boardregdate = $data['boardregdate'];
  
  // 이게 로그인한 id가 담긴 정보임
  $loginid = $_SESSION['userid'];
?>


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>글보기</title>
</head>
<body>
  <!-- 로그아웃은 어디에서든 다해야한다. 보통 nav에 있겠지, -->
  <a href="../logout.php">로그아웃</a>
  <table border="1" width="800">
    <tr>
      <th>제목</th>
      <td><?=$boardtitle?></td>
    </tr>
    <tr>
      <th>작성자</th>
      <td><?=$userid?></td>
    </tr>
    <tr>
      <th>날짜</th>
      <td><?=$boardregdate?></td>
    </tr>
    <tr>
      <th>조회수</th>
      <td><?=$boardhit?></td>
    </tr>
    <tr>
      <!-- 아래의 스크립트 태그에서 dom요소로 가져오기 위해 id를 설정 -->
      <th>좋아요</th>
      <td id="like"><?=$boardlike?></td>
    </tr>
    <tr>
      <th>내용</th>
      <td><?=$boardcontent?></td>
    </tr>
    <!-- 수정, 삭제와 좋아요 누르기 기능을 추가해보자 -->
    <!--로그인 사용자와 글을 쓴 사용자가 동일하면 수정, 삭제 버튼을 만들어 주어야한다. -->
    <tr>
      <td colspan="2">
        <?php
          if($userid == $loginid){
        ?>
        <a href="./edit.php?boardidx=<?=$boardidx?>">수정</a>
        <a href="./delete.php?boardidx=<?=$boardidx?>">삭제</a>
        <?php
          } else {
        ?>
        <!-- 좋아요 버튼은 내가 쓴 글에는 보이지 않아야 한다. -->
        <!-- like 함수를 만들어 like를 추가하는 동적페이지를 추가하자 -->
        <img src="../images/like.png" alt="좋아요" width="20" onclick="like();">
        <?php
          }
        ?>
        <a href="./list.php">리스트</a>
      </td>
    </tr>
  </table>
  <!-- 댓글 달기를 추가하자 -->
  <hr>
  <form action="reply_ok.php" method="post">
    <!-- 댓글 달기도 idx를 표현할 필요없지만 댓글이 달리는 idx번호가 필요하다.-->
    <input type="hidden" name="boardidx" value="<?=$boardidx?>">
   <p>
     <!-- 댓글을 다는 input을 만듦 -->
     <?=$loginid?> : <input type="text" name="replycontent" size="60">
      <input type="submit" value="확인">
   </p>
  </form>
  <!-- 달려 있는 댓글을 가져옴  댓글의 데이터베이스 테이블은 따로 관리한다.-->
  <!-- 댓글의 idx는 따로 관리되지만 댓글이 달린 위치를 알기위해 boardidx 레이블을 추가함 -->
  <hr>
  <?php
    $sql = "select replyidx,userid,replycontent,replyregdate from tb_reply where boardidx=$boardidx order by replyidx desc";
    $result = mysqli_query($conn, $sql);
    // result가 끝날때까지 반복하여 값을 가져옴
    while($data = mysqli_fetch_array($result)){
      $replyidx = $data['replyidx'];
      $userid = $data['userid'];
      $replycontent = $data['replycontent'];
      $replyregdate = $data['replyregdate'];
  ?>
  <!-- while로 반복시킨 값들을 표시함 -->
  <p><?=$userid?> : <?=$replycontent?> (<?=$replyregdate?>)</p>
  <?php
    }
  ?>
</body>
<script>
  function like(){
    // xml을 사용하여 특정부분만 갱신하자
    const xhr = new XMLHttpRequest();
    // state가 바뀌때마다 실행되는 내장 함수
    xhr.onreadystatechange = function(){
      // readyStatus가 Done 이면 4
      if(xhr.readyState == XMLHttpRequest.DONE){
        // 통신이 원활하면 200
        if(xhr.status == 200){
          alert("좋아요");
          // responseText는 like_ok.php를 별도로 만들어 데이터베이스에서 가져온 자료를 문자열로 받음
          document.getElementById('like').innerHTML = xhr.responseText;
          console.log(xhr.responseText)
        }
      }
    }
    // get방식으로 현재 열려있는 테이블 게시판 번호를 넘겨주고 데이터베이스 통신이 원활하면 like_ok.php 정상적으로 실행하여 boardlike 행을 정상적으로 update할 것이고 이를 가져오게 될 것이다
    xhr.open("GET", "like_ok.php?boardidx=<?=$boardidx?>", true);
    xhr.send();
  }
</script>
</html>

like_ok.php

  • 좋아요 버튼을 누르면 실행됨
  • like 갯수를 update하여 다시 like 갯수를 가져온다.
<?php
  include "../include/dbconn.php";
  include "../include/logincheck.php";

  $boardidx = $_GET['boardidx'];
  // like의 갯수를 update함.
  $sql = "update tb_board set boardlike = boardlike + 1 where boardidx = $boardidx";
  $result = mysqli_query($conn, $sql);

  // 다시 boardlike를 가져옴 
  $sql = "select boardlike from tb_board where boardidx = $boardidx";
  $result = mysqli_query($conn,$sql);
  $data = mysqli_fetch_array($result);
  // echo로 바로 해당 데이터를 출력을 해야 XMLHttp에서 이 문자를 인식한다.
  echo $data['boardlike'];
?>

write.php

  • list.php의 글쓰기에 연결되어 있다.
  • write_ok.php로 데이터를 보낸다.
<?php
  include "../include/logincheck.php";
  // 로그인 한 상태라면 session에 로그인 id가 남아있을 것이다. 
  $userid = $_SESSION['userid'];
?>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>글쓰기</title>
</head>
<body>
  <h2>글쓰기</h2>
  <!-- 글 쓰기를 완료하면 write_ok.php로 데이터를 보낸다. -->
  <form action="write_ok.php" method="post">
    <p>아이디 : <?=$userid?> </p>
    <p>제목 : <input type="text" name="boardtitle"></p>
    <p>내용</p>
    <p><textarea name="boardcontent" cols="40" rows="10"></textarea></p>
    <p>
      <input type="submit" value="확인">
      <input type="reset" value="다시작성">
      <input type="button" value="리스트" onclick="location.href='list.php'">
    </p>
  </form>
</body>
</html>

write_ok.php

  • 받아온 데이터들을 데이터베이스와 통신하여 insert한다.
<?php
    include "../include/dbconn.php";
    include "../include/logincheck.php";

    // write.php로부터 받아온 데이터들을 sql을 통하여 데이터베이스에 저장한다.
    // 읽기는 list.php에서 읽을 것이다. 
    $userid = $_SESSION['userid'];
    $boardtitle = $_POST['boardtitle'];
    $boardcontent = $_POST['boardcontent'];

    $sql = "insert into tb_board (userid, boardtitle, boardcontent) values ('$userid', '$boardtitle', '$boardcontent')";
    $result = mysqli_query($conn, $sql);

    echo "<script>alert('작성완료');location.href = './list.php';</script>"
?>
  • 다시 리스트로 돌려보내어 최신화된 데이터를 읽어 가져오도록 한다.

reply_ok.php

  • detail.php에 연결되어 있음.
  • 댓글 쓰기를 하면 reply_ok로 post방식으로 보내져 해당 php에서 처리된다.
  • post방식으로 받은 데이터들을 insert한다.(물론 해당되는 데이터베이스 테이블이 존재한다.)
<?php
  include "../include/logincheck.php";
  include "../include/dbconn.php";
  
  $boardidx = $_POST['boardidx'];
  $replycontent = $_POST['replycontent'];
  $userid = $_SESSION['userid'];

  $sql = "insert into tb_reply (boardidx, replycontent, userid) values ($boardidx,'$replycontent','$userid')";
  $result = mysqli_query($conn, $sql);

  echo "<script>alert('댓글 작성 완료!'); location.href='./detail.php?boardidx=$boardidx';</script>";
?>

edit.php

  • 수정하기는 먼저 수정되는 게시글의 정보를 데이터베이스에서 가져오고 기존 데이터베이스를 뷰단에 입력시킨다.
  • 원하는 부분을 수정하고 submit이 있는 버튼을 누르면 post 방식으로 edit_ok.php에 요청하게 된다.
<?php
  include "../include/dbconn.php";
  include "../include/logincheck.php";

  $boardidx = $_GET['boardidx'];
  $sql = "select * from tb_board where boardidx = $boardidx";
  $result = mysqli_query($conn,$sql);
  $data = mysqli_fetch_array($result);

  $boardtitle = $data['boardtitle'];
  $boardcontent = $data['boardcontent'];
  $userid = $_SESSION['userid'];
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>글 수정</title>
</head>
<body>
  <h2>글 수정</h2>
  <form action="edit_ok.php" method="post">
    <!-- boardidx를 수정할 필요는 없지만 idx번호로 수정하고자 하는 글을 결정해주어야 함 -->
    <input type="hidden" name="boardidx" value="<?=$boardidx?>">
    <p>아이디 : <?=$userid?></p>
    <p>제목 : <input type="text" name="boardtitle" value = "<?=$boardtitle?>"></p>
    <p>내용</p>
    <p>
      <textarea name="boardcontent" cols="40" rows="10"><?=$boardcontent?></textarea>
    </p>
    <p>
      <input type="submit" value="확인">
      <input type="reset" value="다시작성">
      <input type="button" value="리스트" onclick="location.href='list.php'"> 
    </p>
  </form>
</body>
</html>

edit_ok.php

  • 수정된 데이터를 받아 새롭게 해당 데이터를 update 시킨다.
<!-- 수정을 하고 바뀐 정보들을 받아서 데이터베이스와 통신을 하고 자료를 update한다음 detail로 복귀 -->
<!-- 수정된 자료는 detail.php에서 확인 가능 -->
<?php
  include "../include/dbconn.php";
  include "../include/logincheck.php";

  // 수정된 데이터를 가져옴
  $boardidx = $_POST['boardidx'];
  $boardtitle = $_POST['boardtitle'];
  $boardcontent = $_POST['boardcontent'];

  // 수정된 데이터를 데이터베이스에 update 시킴
  $sql = "update tb_board set boardtitle = '$boardtitle', boardcontent = '$boardcontent' where boardidx= '$boardidx'";

  $result = mysqli_query($conn, $sql);
  // datail로 돌려 보냄
  echo "<script>alert('{$boardidx}수정완료');location.href='detail.php?boardidx=$boardidx';</script>"

?>

delete.php

  • 해당 게시글의 idx정보를 get방식으로 받아 데이터베이스에 해당 idx의 정보 삭제를 요청한다.
<!-- 삭제를 처리하는 페이지 -->
<?php
  include "../include/dbconn.php";
  include "../include/logincheck.php";

  //삭제하고자하는 게시판의 idx를 가져옴
  $boardidx = $_GET['boardidx'];

  $sql = "delete from tb_board where boardidx = $boardidx";
  $result = mysqli_query($conn, $sql);
  echo "<script>alert('{$boardidx}번 게시글이 삭제되었습니다.');location.href='list.php'</script>"

?>
profile
AllTimeDevelop

0개의 댓글