반응형

전에 올린 댓글에 이미지 첨부하기 소스에 오류가 있어서 바로 잡고자 한다. 예전 소스에는 메모에 첨부 파일이 무조건 있는 경우라고 작업을 했다. 그래서 첨부 이미지가 없으면 오류가 난다. 그 부분을 수정해 보자.

 

댓글에 저장하는 이미지의 정보를 저장하는 테이블을 만든다.

 

CREATE TABLE `file_table_memo` (
  `fid` int(11) NOT NULL AUTO_INCREMENT,
  `bid` int(11) DEFAULT NULL,
  `userid` varchar(100) DEFAULT NULL,
  `filename` varchar(100) DEFAULT NULL,
  `regdate` datetime DEFAULT current_timestamp(),
  `status` tinyint(4) DEFAULT 1,
  `memoid` int(11) DEFAULT NULL,
  `type` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`fid`),
  KEY `idx_file_table_userid` (`userid`),
  KEY `idx_file_table_type` (`type`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4;

 

view.php 를 수정한다.

 

/view.php

 

<?php
include $_SERVER["DOCUMENT_ROOT"]."/inc/header.php";

$bid=$_GET["bid"];
$result = $mysqli->query("select * from board where bid=".$bid) or die("query error => ".$mysqli->error);
$rs = $result->fetch_object();

$query="select *, m.userid, m.regdate, m.memoid from memo m
left join file_table_memo f on m.memoid=f.memoid
where m.status=1 and m.bid=".$rs->bid." order by m.memoid asc";//메모에 꼭 첨부파일이 있는 것은 아니므로 left join을 사용한다.
$memo_result = $mysqli->query($query) or die("query error => ".$mysqli->error);
while($mrs = $memo_result->fetch_object()){
    $memoArray[]=$mrs;
}

$fquery="select * from file_table where status=1 and bid=".$rs->bid." and memoid is null order by fid asc";
$file_result = $mysqli->query($fquery) or die("query error => ".$mysqli->error);
while($frs = $file_result->fetch_object()){
    $fileArray[]=$frs;
}

$query2="select type,count(*) as cnt from recommend r where bid=".$rs->bid." group by type";
$rec_result = $mysqli->query($query2) or die("query error => ".$mysqli->error);
while($recs = $rec_result->fetch_object()){
  $recommend[$recs->type] = $recs->cnt;
}

?>

<style>
  img {
    max-width:90%;
  }
</style>

      <h3 class="pb-4 mb-4 fst-italic border-bottom" style="text-align:center;">
        - 게시판 보기 -
      </h3>

      <article class="blog-post">
        <h2 class="blog-post-title"><?php echo $rs->subject;?></h2>
        <p class="blog-post-meta"><?php echo $rs->regdate;?> by <a href="#"><?php echo $rs->userid;?></a></p>

        <hr>
        <?php
          foreach($fileArray as $fa){
        ?>
          <p><img src="/data/<?php echo $fa->filename;?>"></p>
        <?php }?>
        <p>
          <?php echo $rs->content;?>
        </p>
       
        <div style="text-align:center;">
          <button type="button" class="btn btn-lg btn-primary" id="like_button">추천&nbsp;<span id="like"><?php echo number_format($recommend['like']);?></span></button>
          <button type="button" class="btn btn-lg btn-warning" id="hate_button">반대&nbsp;<span id="hate"><?php echo number_format($recommend['hate']);?></span></button>
        </div>
        <hr>
      </article>

     

      <nav class="blog-pagination" aria-label="Pagination">
        <a class="btn btn-outline-secondary" href="/index.php">목록</a>
        <a class="btn btn-outline-secondary" href="/write.php?parent_id=<?php echo $rs->bid;?>">답글</a>
        <a class="btn btn-outline-secondary" href="/write.php?bid=<?php echo $rs->bid;?>">수정</a>
        <a class="btn btn-outline-secondary" href="/delete.php?bid=<?php echo $rs->bid;?>" onclick="return confirm('삭제하시겠습니까?');">삭제</a>
      </nav>

      <div style="margin-top:20px;">
        <form class="row g-3">
          <input type="hidden" name="file_table_id" id="file_table_id" value="">
          <div class="col-md-8">
            <textarea class="form-control" placeholder="댓글을 입력해주세요." id="memo" style="height: 60px"></textarea>
          </div>
          <div class="col-md-2">
            <button type="button" class="btn btn-secondary" id="memo_button">댓글등록</button>
          </div>
          <div class="col-md-2" id="memo_image">
            <input type="file" name="upfile" id="upfile" />
          </div>
        </form>
      </div>
      <div id="memo_place">
      <?php
        foreach($memoArray as $ma){
      ?>
        <div class="card mb-4" id="memo_<?php echo $ma->memoid?>" style="max-width: 100%;margin-top:20px;">
          <div class="row g-0">
            <div class="col-md-12">
              <div class="card-body">
                <p class="card-text">
                <?php
                if($ma->filename){
                ?>
                <img src="/data/<?php echo $ma->filename;?>" style="max-width:90%;">
                <?php }?>
                <br>  
                <?php echo $ma->memo;?></p>
                <p class="card-text"><small class="text-muted"><?php echo $ma->userid;?> / <?php echo $ma->regdate;?></small></p>
                <p class="card-text" style="text-align:right"><a href="javascript:;" onclick="memo_modi(<?php echo $ma->memoid?>)">수정</a> / <a href="javascript:;" onclick="memo_del(<?php echo $ma->memoid?>)">삭제</a></p>
              </div>
            </div>
          </div>
        </div>
      <?php }?>
      </div>

<script>

  $("#upfile").change(function(){

    var files = $('#upfile').prop('files');
    for(var i=0; i < files.length; i++) {
        attachFile(files[i]);
    }

    $('#upfile').val('');

  });  

  function attachFile(file) {
    var formData = new FormData();
    formData.append("savefile", file);
    $.ajax({
        url: 'save_image_memo.php',
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        dataType : 'json' ,
        type: 'POST',
        success: function (return_data) {
            if(return_data.result=="member"){
                alert('로그인 하십시오.');
                return;
            }else if(return_data.result=="size"){
                alert('10메가 이하만 첨부할 수 있습니다.');
                return;
            }else if(return_data.result=="image"){
                alert('이미지 파일만 첨부할 수 있습니다.');
                return;
            }else if(return_data.result=="error"){
                alert('첨부하지 못했습니다. 관리자에게 문의하십시오.');
                return;
            }else{
                $("#file_table_id").val(return_data.fid);
                var html = "<div class='col' id='f_"+return_data.fid+"'><div class='card h-100'><img src='/data/"+return_data.savename+"' class='card-img-top'><div class='card-body'><button type='button' class='btn btn-warning' onclick='file_del("+return_data.fid+")'>삭제</button></div></div></div>";
                $("#upfile").hide();
                $("#memo_image").append(html);
            }
        }
    });

  }

  function file_del(fid){

    if(!confirm('삭제하시겠습니까?')){
    return false;
    }

    var data = {
        fid : fid
    };
        $.ajax({
            async : false ,
            type : 'post' ,
            url : 'file_delete.php' ,
            data  : data ,
            dataType : 'json' ,
            error : function() {} ,
            success : function(return_data) {
                if(return_data.result=="member"){
                    alert('로그인 하십시오.');
                    return;
                }else if(return_data.result=="my"){
                    alert('본인이 작성한 글만 삭제할 수 있습니다.');
                    return;
                }else if(return_data.result=="no"){
                    alert('삭제하지 못했습니다. 관리자에게 문의하십시오.');
                    return;
                }else{
                    $("#file_table_id").val('');
                    $("#f_"+fid).hide();
                    $("#upfile").show();
                }
            }
    });

    }

  $("#like_button").click(function () {

    if(!confirm('추천하시겠습니까?')){
      return false;
    }
     
      var data = {
          type : 'like' ,
          bid : <?php echo $bid;?>
      };
          $.ajax({
              async : false ,
              type : 'post' ,
              url : 'like_hate.php' ,
              data  : data ,
              dataType : 'json' ,
              error : function() {} ,
              success : function(return_data) {
                if(return_data.result=="member"){
                  alert('로그인 하십시오.');
                  return;
                }else if(return_data.result=="check"){
                  alert('이미 추천이나 반대를 하셨습니다.');
                  return;
                }else if(return_data.result=="no"){
                  alert('다시한번 시도해주십시오.');
                  return;
                }else{
                  $("#like").text(return_data.cnt);
                }
              }
          });
  });

  $("#hate_button").click(function () {

    if(!confirm('반대하시겠습니까?')){
      return false;
    }
     
      var data = {
          type : 'hate' ,
          bid : <?php echo $bid;?>
      };
          $.ajax({
              async : false ,
              type : 'post' ,
              url : 'like_hate.php' ,
              data  : data ,
              dataType : 'json' ,
              error : function() {} ,
              success : function(return_data) {
                if(return_data.result=="member"){
                  alert('로그인 하십시오.');
                  return;
                }else if(return_data.result=="check"){
                  alert('이미 추천이나 반대를 하셨습니다.');
                  return;
                }else if(return_data.result=="no"){
                  alert('다시한번 시도해주십시오.');
                  return;
                }else{
                  $("#hate").text(return_data.cnt);
                }
              }
          });
  });


  $("#memo_button").click(function () {
        var file_table_id = $("#file_table_id").val();
        var data = {
            memo : $('#memo').val() ,
            bid : <?php echo $bid;?>,
            file_table_id : file_table_id
        };
            $.ajax({
                async : false ,
                type : 'post' ,
                url : 'memo_write.php' ,
                data  : data ,
                dataType : 'html' ,
                error : function() {} ,
                success : function(return_data) {
                  if(return_data=="member"){
                    alert('로그인 하십시오.');
                    return;
                  }else{
                    $('#memo').val('')
                    $("#file_table_id").val('');
                    $("#f_"+file_table_id).hide();
                    $("#upfile").show();
                    $("#memo_place").append(return_data);
                  }
                }
        });
    });

  function memo_del(memoid){

    if(!confirm('삭제하시겠습니까?')){
      return false;
    }
   
    var data = {
        memoid : memoid
    };
        $.ajax({
            async : false ,
            type : 'post' ,
            url : 'memo_delete.php' ,
            data  : data ,
            dataType : 'json' ,
            error : function() {} ,
            success : function(return_data) {
              if(return_data.result=="member"){
                alert('로그인 하십시오.');
                return;
              }else if(return_data.result=="my"){
                alert('본인이 작성한 글만 삭제할 수 있습니다.');
                return;
              }else if(return_data.result=="no"){
                alert('삭제하지 못했습니다. 관리자에게 문의하십시오.');
                return;
              }else{
                $("#memo_"+memoid).hide();
              }
            }
    });

  }

  function memo_modi(memoid){

    var data = {
        memoid : memoid
    };
   
    $.ajax({
          async : false ,
          type : 'post' ,
          url : 'memo_modify.php' ,
          data  : data ,
          dataType : 'html' ,
          error : function() {} ,
          success : function(return_data) {
            if(return_data=="member"){
              alert('로그인 하십시오.');
              return;
            }else if(return_data=="my"){
              alert('본인이 작성한 글만 수정할 수 있습니다.');
              return;
            }else if(return_data=="no"){
              alert('수정하지 못했습니다. 관리자에게 문의하십시오.');
              return;
            }else{
              $("#memo_"+memoid).html(return_data);
            }
          }
    });

  }

  function memo_modify(memoid){

    var data = {
        memoid : memoid,
        memo : $('#memo_text_'+memoid).val()
    };

    $.ajax({
          async : false ,
          type : 'post' ,
          url : 'memo_modify_update.php' ,
          data  : data ,
          dataType : 'html' ,
          error : function() {} ,
          success : function(return_data) {
            if(return_data=="member"){
              alert('로그인 하십시오.');
              return;
            }else if(return_data=="my"){
              alert('본인이 작성한 글만 수정할 수 있습니다.');
              return;
            }else if(return_data=="no"){
              alert('수정하지 못했습니다. 관리자에게 문의하십시오.');
              return;
            }else{
              $("#memo_"+memoid).html(return_data);
            }
          }
    });

    }

</script>

<?php
include $_SERVER["DOCUMENT_ROOT"]."/inc/footer.php";
?>

 

10번째줄에 쿼리를 수정했다. 모든 댓글에 첨부파일이 있는건 아니므로 join이 아니고 left join으로 바꿨다.

 

댓글의 이미지를 첨부했을때 저장해주는 파일을 만들어보자.

 

/save_image_memo.php

<?php session_start();
include $_SERVER["DOCUMENT_ROOT"]."/inc/dbcon.php";
ini_set( 'display_errors', '0' );

if(!$_SESSION['UID']){
    $retun_data = array("result"=>"member");
    echo json_encode($retun_data);
    exit;
}

if($_FILES['savefile']['size']>10240000){//10메가
    $retun_data = array("result"=>"size");
    echo json_encode($retun_data);
    exit;
}

if($_FILES['savefile']['type']!='image/jpeg' and $_FILES['savefile']['type']!='image/gif' and $_FILES['savefile']['type']!='image/png'){//이미지가 아니면, 다른 type은 and로 추가
    $retun_data = array("result"=>"image");
    echo json_encode($retun_data);
    exit;
}

$save_dir = $_SERVER['DOCUMENT_ROOT']."/data/";//파일을 업로드할 디렉토리
$filename = $_FILES["savefile"]["name"];
$ext = pathinfo($filename,PATHINFO_EXTENSION);//확장자 구하기
$newfilename = date("YmdHis").substr(rand(),0,6);
$savefile = $newfilename.".".$ext;//새로운 파일이름과 확장자를 합친다

if(move_uploaded_file($_FILES["savefile"]["tmp_name"], $save_dir.$savefile)){//파일 등록에 성공하면 디비에 등록해준다.
    $sql="INSERT INTO testdb.file_table_memo
    (userid, filename)
    VALUES('".$_SESSION['UID']."', '".$savefile."')";
    $result = $mysqli->query($sql) or die($mysqli->error);
    $fid = $mysqli -> insert_id;
    $retun_data = array("result"=>"success", "fid"=>$fid, "savename"=>$savefile);
    echo json_encode($retun_data);
    exit;
}else{
    $retun_data = array("result"=>"error");
    echo json_encode($retun_data);
    exit;
}


?>

 

이번엔 댓글을 작성 후 저장하는 파일을 수정해보자.

 

/memo_write.php

<?php session_start();
include $_SERVER["DOCUMENT_ROOT"]."/inc/dbcon.php";
ini_set( 'display_errors', '0' );

if(!$_SESSION['UID']){
    echo "member";
    exit;
}

$memo  = $_POST['memo'];
$bid  = $_POST['bid'];
$memoid = $_POST['memoid']??0;
$file_table_id = $_POST['file_table_id'];

$sql="INSERT INTO memo
(bid, pid, userid, memo, status)
VALUES(".$bid.", ".$memoid.", '".$_SESSION['UID']."', '".$memo."', 1)";
$result=$mysqli->query($sql) or die($mysqli->error);
if($result)$last_memoid = $mysqli -> insert_id;

//메모 첨부 이미지 업데이트
if($file_table_id){//첨부한 파일이 있는 경우에만
  $uq="update file_table_memo set bid=".$bid.", memoid=".$last_memoid." where fid=".$file_table_id;
  $ur=$mysqli->query($uq) or die($mysqli->error);

  $fquery="select * from file_table_memo where status=1 and fid=".$file_table_id;
  $file_result = $mysqli->query($fquery) or die("query error => ".$mysqli->error);
  $frs = $file_result->fetch_object();
  $img = "<img src='/data/".$frs->filename."' style='max-width:90%'>";
}

echo "<div class=\"card mb-4\" id=\"memo_".$last_memoid."\" style=\"max-width: 100%;margin-top:20px;\">
<div class=\"row g-0\">
    <div class=\"col-md-12\">
    <div class=\"card-body\">
      <p class=\"card-text\">".$img."<br>".$memo."</p>
      <p class=\"card-text\"><small class=\"text-muted\">".$_SESSION['UID']." / now</small></p>
      <p class=\"card-text\" style=\"text-align:right\"><a href=\"javascript:;\" onclick=\"memo_modi(".$last_memoid.")\">수정</a> / <a href=\"javascript:;\" onclick=\"memo_del(".$last_memoid.")\">삭제</a></p>
    </div>
  </div>
</div>
</div>";

?>
   

 

마찬가지로 첨부 파일이 없는 경우도 있으므로 없을때는 첨부 파일 처리 부분을 건너 뛴다.

 

이번엔 댓글을 삭제하는 경우다.

 

/memo_delete.php

 

<?php session_start();
include $_SERVER["DOCUMENT_ROOT"]."/inc/dbcon.php";
ini_set( 'display_errors', '0' );

if(!$_SESSION['UID']){
    $retun_data = array("result"=>"member");
    echo json_encode($retun_data);
    exit;
}

$memoid = $_POST['memoid'];

$result = $mysqli->query("select * from memo where memoid=".$memoid) or die("query error => ".$mysqli->error);
$rs = $result->fetch_object();

if($rs->userid!=$_SESSION['UID']){
    $retun_data = array("result"=>"my");
    echo json_encode($retun_data);
    exit;
}

$sql="update memo set status=0 where memoid=".$memoid;//status값을 바꿔준다.
$result=$mysqli->query($sql) or die($mysqli->error);
if($result){
   
    $fquery="select * from file_table_memo where status=1 and memoid=".$memoid;
    $file_result = $mysqli->query($fquery) or die("query error => ".$mysqli->error);
    $frs = $file_result->fetch_object();
    if($frs->filename){//첨부한 파일이 있는 경우에만 삭제처리
        $delete_file=$_SERVER["DOCUMENT_ROOT"]."/data/".$frs->filename;
        if(unlink($delete_file)){
            $sql2="update file_table_memo set status=0 where fid=".$frs->fid;//status값을 바꿔준다.
            $result2=$mysqli->query($sql2) or die($mysqli->error);
        }
    }

    $retun_data = array("result"=>"ok");
    echo json_encode($retun_data);
}else{
    $retun_data = array("result"=>"no");
    echo json_encode($retun_data);
}

?>
       

여기서도 마찬가지로 첨부파일 부분을 수정해줬다. 이번엔 댓글을 수정하는 경우다.

 

/memo_modify_update.php

 

<?php session_start();
include $_SERVER["DOCUMENT_ROOT"]."/inc/dbcon.php";
ini_set( 'display_errors', '0' );

if(!$_SESSION['UID']){
    echo "member";
    exit;
}

$memoid = $_POST['memoid'];
$memo = $_POST['memo'];

$result = $mysqli->query("select * from memo where memoid=".$memoid) or die("query error => ".$mysqli->error);
$rs = $result->fetch_object();

if($rs->userid!=$_SESSION['UID']){
    echo "my";
    exit;
}

$sql="update memo set memo='".$memo."' where memoid=".$memoid;//status값을 바꿔준다.
$result=$mysqli->query($sql) or die($mysqli->error);

$fquery="select * from file_table_memo where status=1 and memoid=".$memoid;
$file_result = $mysqli->query($fquery) or die("query error => ".$mysqli->error);
$frs = $file_result->fetch_object();
if($frs->filename){//첨부한파일이 있는 경우에만 표시하기
  $img = "<img src='/data/".$frs->filename."' style='max-width:90%'>";
}


echo "<div class=\"row g-0\">
    <div class=\"col-md-12\">
    <div class=\"card-body\">
      <p class=\"card-text\">".$img."<br>".$memo."</p>
      <p class=\"card-text\"><small class=\"text-muted\">".$_SESSION['UID']." / now</small></p>
      <p class=\"card-text\" style=\"text-align:right\"><a href=\"javascript:;\" onclick=\"memo_modi(".$memoid.")\">수정</a> / <a href=\"javascript:;\" onclick=\"memo_del(".$memoid.")\">삭제</a></p>
    </div>
  </div>
</div>";

?>
   

여기도 첨부 파일 부분을 처리해준다.

반응형

+ Recent posts