게시판에 글을 쓸때 첨부 파일을 여러개 선택해서 등록하는 것을 해보려고 한다. 글쓰기 페이지를 수정한다.
/app/Views/board_write.php
<form method="post" action="<?= site_url('/writeSave') ?>" enctype="multipart/form-data">
<input type="hidden" name="bid" value="<?php echo isset($view->bid)?$view->bid:0;?>">
<div class="mb-3">
<label for="exampleFormControlInput1" class="form-label">이름</label>
<input type="text" name="username" class="form-control" id="exampleFormControlInput1" placeholder="이름을 입력하세요." value="<?php echo $_SESSION['username']?>">
</div>
<div class="mb-3">
<label for="exampleFormControlInput1" class="form-label">제목</label>
<input type="text" name="subject" class="form-control" id="exampleFormControlInput1" placeholder="제목을 입력하세요." value="<?php echo isset($view->subject)?$view->subject:'';?>">
</div>
<div class="mb-3">
<label for="exampleFormControlTextarea1" class="form-label">내용</label>
<textarea class="form-control" id="exampleFormControlTextarea1" name="content" rows="3"><?php echo isset($view->content)?$view->content:'';?></textarea>
</div>
<div class="mb-3">
<input type="file" multiple name="upfile[]" id="upfile" class="form-control form-control-lg" aria-label="Large file input example">
</div>
<br />
<?php
$btntitle=isset($view->bid)?"수정":"등록";
?>
<button type="submit" class="btn btn-primary"><?php echo $btntitle;?></button>
</form>
<input type="file" multiple name="upfile[]" id="upfile" class="form-control form-control-lg" aria-label="Large file input example">
multiple 을 추가했고 파일 변수를 upfile[] 로 수정했다. 여러개를 입력할거니까 배열로 넘겨주어야 한다. 이제 처리해주는 컨트롤러를 수정한다.
/app/Controllers/Board.php
<?php
namespace App\Controllers;
use App\Models\BoardModel;//사용할 모델을 반드시 써줘야한다.
class Board extends BaseController
{
public function list()
{
$db = db_connect();
$query = "select * from board order by bid desc";
$rs = $db->query($query);
$data['list'] = $rs->getResult();//결과값 저장
return render('board_list', $data);//view에 리턴
}
public function write()
{
if(!isset($_SESSION['userid'])){
echo "<script>alert('로그인하십시오.');location.href='/login'</script>";
exit;
}
return render('board_write');
}
public function save()
{
if(!isset($_SESSION['userid'])){
echo "<script>alert('로그인하십시오.');location.href='/login'</script>";
exit;
}
$db = db_connect();
$bid=$this->request->getVar('bid');//bid값이 있으면 수정이고 아니면 등록이다.
$subject=$this->request->getVar('subject');
$content=$this->request->getVar('content');
if($bid){
$query = "select * from board where bid=".$bid;
$rs = $db->query($query);
if($_SESSION['userid']==$rs->getRow()->userid){
$sql="update board set subject='".$subject."', content='".$content."' where bid=".$bid;
$rs = $db->query($sql);
return $this->response->redirect(site_url('/boardView/'.$bid));
}else{
echo "<script>alert('본인이 작성한 글만 수정할 수 있습니다.');location.href='/login';</script>";
exit;
}
}
//$file = $this->request->getFile('upfile');//첨부한 파일의 정보를 가져온다.
$files = $this->request->getFileMultiple("upfile"); //다중 업로드 파일 정보
$filepath = array();
foreach($files as $file){
if($file->getName()){//파일 정보가 있으면 저장한다.
$filename = $file->getName();//기존 파일명을 저장할때 필요하다. 여기서는 사용하지 않는다.
//$filepath = WRITEPATH. 'uploads/' . $file->store(); 매뉴얼에 나와있는 파일 저장 방법이다.여기서는 안쓴다.
$newName = $file->getRandomName();//서버에 저장할때 파일명을 바꿔준다.
$filepath[] = $file->store('board/', $newName);//CI4의 store 함수를 이용해 저장한다. 저장한 파일의 경로와 파일명을 리턴, 배열로 저장한다.
}
}
$sql="insert into board (userid,subject,content) values ('".$_SESSION['userid']."','".$subject."','".$content."')";
$rs = $db->query($sql);
$insertid=$db->insertID();
foreach($filepath as $fp){//배열로 저장한 파일 저장 정보를 디비에 입력한다.
if(isset($fp)){
$sql2="INSERT INTO file_table
(bid, userid, filename, type)
VALUES('".$insertid."', '".$_SESSION['userid']."', '".$fp."', 'board')";
$rs2 = $db->query($sql2);
}
}
return $this->response->redirect(site_url('/boardView/'.$insertid));
}
public function view($bid = null)
{
$db = db_connect();
$query = "select b.*,(select GROUP_CONCAT(filename) from file_table f where f.type='board' and f.bid=b.bid) as fs from board b where b.bid=".$bid;
$rs = $db->query($query);
$data['view'] = $rs->getRow();
return render('board_view', $data);
}
public function modify($bid = null)
{
$db = db_connect();
$query = "select * from board where bid=".$bid;
$rs = $db->query($query);
if($_SESSION['userid']==$rs->getRow()->userid){
$data['view'] = $rs->getRow();
return render('board_write', $data);
}else{
echo "<script>alert('본인이 작성한 글만 수정할 수 있습니다.');location.href='/login';</script>";
exit;
}
}
public function delete($bid = null)
{
$db = db_connect();
$query = "select * from board where bid=".$bid;
$rs = $db->query($query);
if($_SESSION['userid']==$rs->getRow()->userid){
$query3 = "select * from file_table where type='board' and bid=".$bid;
$rs3 = $db->query($query3);
$fs=$rs3->getResult();
foreach($fs as $f3){
unlink('uploads/'.$f3->filename);
}
$query4 = "delete from file_table where type='board' and bid=".$bid;
$rs4 = $db->query($query4);
$query2 = "delete from board where bid=".$bid;
$rs2 = $db->query($query2);
return $this->response->redirect(site_url('/board'));
}else{
echo "<script>alert('본인이 작성한 글만 삭제할 수 있습니다.');location.href='/login';</script>";
exit;
}
}
}
파일 업로드를 처리해주는 부분에서 달라졌다. 다중 파일을 받을 수 있도록 변수를 수정했고 받은 파일 정보를 foreach를 이용해서 서버에 저장한다. 그리고 등록한 파일의 정보를 디비에 저장했다. 또 등록이 되면 바로 view 페이지로 이동하도록 수정했다.
view() 함수를 한번 보자. 뭔가 수정한게 보인다.
$query = "select b.*,(select GROUP_CONCAT(filename) from file_table f where f.type='board' and f.bid=b.bid) as fs from board b where b.bid=".$bid;
쿼리를 수정했다. 게시판의 정보를 가져오면서 첨부한 파일이 있으면 첨부한 파일의 정보를 모두 가져오도록 쿼리를 수정했다. GROUP_CONCAT 함수를 이용하면 가져오는 모든 내용을 , 로 자동 구분해준다.
이제 view 파일을 수정해보자.
/app/Views/board_view.php
<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 $view->subject;?></h2>
<p class="blog-post-meta"><?php echo $view->regdate;?> by <a href="#"><?php echo $view->userid;?></a></p>
<hr>
<p>
<?php echo $view->content;?>
</p>
<br>
<?php
if(isset($view->fs)){
$vfs = explode(",",$view->fs);
foreach($vfs as $img){
if(isset($img)){
?>
<img src="<?php echo base_url('/uploads/'.$img);?>">
<?php
}
}
}?>
<hr>
<p style="text-align:right;">
<?php
if($_SESSION['userid']==$view->userid){
?>
<a href="/modify/<?php echo $view->bid;?>"><button type="button" class="btn btn-primary">수정</button><a>
<a href="/delete/<?php echo $view->bid;?>"><button type="button" class="btn btn-warning">삭제</button><a>
<?php }?>
<a href="/board"><button type="button" class="btn btn-primary">목록</button><a>
</p>
</article>
컨트롤러에서 받은 첨부 파일 정보를 받아서 화면에 뿌려준다.
이번엔 삭제를 보자. 삭제에 관련된 컨트롤러도 위에 있는 컨트롤러에 이미 들어 있다.
마찬가지로 파일의 정보를 불러와서 하나씩 삭제해주고 마지막에 테이블에서 파일 정보와 게시물 정보를 삭제해주면 된다.
이렇게 다중 파일 업로드 작업과 삭제하는 작업까지 해보았다. 다음 시간엔 페이징을 해보자.