Today I Learned …

[웹개발] 파일 업로드/다운로드 기능 본문

Web/APM

[웹개발] 파일 업로드/다운로드 기능

염베리 2021. 11. 2. 04:05

* 개인적인 공부 내용을 기록한 글입니다.


사담
죽다살아났다...
내일은 일정이 있어서 빨리 자야하는데 벌써 세시다...ㅠ
요즘 블로그도 그렇고 살짝 날로 먹는 것 같아서 마음이 좀 불편...
보고서는 계속 진행 중... 생각보다 진도가 너무 안나간다 ㅠ

설명
오늘은 파일 업로드/다운로드 기능에 대해 다뤄본다.

최종 화면

클릭하면 확대됩니다.


파일 업로드 기능


0. 전제
게시글 DB에 파일명을 저장할 컬럼을 하나 추가해준 상태이다.


1. 다음은 게시글 작성 페이지를 출력하는 write.php의 폼 내부이다.

<form method="post" action="write_ok.php" enctype="multipart/form-data" autocomplete="off">
	<p><input class=textform type=text size=25 name=title placeholder="제목" required></p>
	<p><textarea class=textform cols=35 rows=15 name=content placeholder="내용을 입력하세요."></textarea></p>
	<p><input class=file id="input-file" type=file name=file></p>
	<p><input class=write type="submit" value="글쓰기"></p>
</form>

[1] <form> 태그 내부에 enctype="multipart/form-data" 를 추가해준다.
⇒ enctype 속성은 method가 POST인 경우에만 사용할 수 있다.
⇒ multipart/form-data 는 모든 문자를 인코딩하지 않음을 명시하는 속성 값으로, 파일이나 이미지를 서버로 전송하는 처리를 할 시 사용한다.
[2] 폼 내부에 type이 file인 <input> 태그를 하나 추가해주고, 이후 php로 처리하기 위해 name 값을 지정해준다.


2. 다음은 게시글 작성을 실질적으로 처리하는 write_ok.php에 추가해줄 내용이다.

$error = $_FILES['file']['error'];
$tmpfile = $_FILES['file']['tmp_name'];
$filename = $_FILES['file']['name'];
$folder = "../file/upload/".$filename;

[1] 혹시 모를 에러를 대비해 에러 정보를 $error에 할당해준다.
[2] 업로드가 진행되는 동안 파일은 tmp 디렉토리에 저장된다. 이 때 자동 생성될 저장명을 $tmpfile에 할당해준다.
[3] 파일의 본래 이름을 $filename에 할당해준다.
[4] 파일이 서버에 최종적으로 저장되었으면 하는 디렉토리의 경로를 $folder에 할당해주고, 뒤에 $filename을 붙여준다.

 

if( $error != UPLOAD_ERR_OK ){
	switch( $error ) {
    		case UPLOAD_ERR_INI_SIZE:
        	case UPLOAD_ERR_FORM_SIZE:
        		echo "<script>alert('파일이 너무 큽니다.');";
            		echo "window.history.back()</script>";
            		exit;
	}
}

[5] 업로드를 시도한 파일이 최대 용량을 초과할 시 바로 에러 정보를 볼 수 있도록 alert 처리를 해준다.
* 다른 종류의 에러도 마찬가지로 에러명을 서치해 switch 구문 안에 넣으면 위 예시처럼 alert를 통해 확인이 가능하다.
[6] 에러를 확인한 후에는 exit 해준다.

 

move_uploaded_file($tmpfile, $folder);

[7] 에러가 출력되지 않았을 시 (= 정상적으로 업로드되었을 시) tmp 디렉토리에 저장되어있는 파일을 아까 지정한 최종 경로로 옮겨준다.

 

$sql = "INSERT INTO board(title, writer, name, written, content, file, hit, liked) VALUES ('$title', '$writer', '$name', now(), '$content', '$filename', 0, 0);";

[8] 게시글 저장을 위한 기존의 INSERT 쿼리문에 [파일명을 저장할 컬럼명]$filename을 추가해준다.

[9] 모든 과정에 문제가 없었다면, 파일을 업로드할 시 최종 경로에 해당 파일이 저장되는 것을 확인할 수 있다.

 

[10] 만약 아무 문제가 없는데도 정상적으로 동작하지 않는다면, 백이면 백 디렉토리의 권한 문제일 것이다.

⇒ 구글링 키워드 : php 파일 업로드 실패 권한


파일 다운로드 기능


1. 다음은 게시글 조회 페이지를 출력하는 view.php의 일부 내용이다.

<div class=middle>
	<p><div class=title><?=$res_view['title'];?></div></p>
	<p><div class=content><?=$res_view['content'];?></div></p>
	<p class=file><a href="../file/upload/<?=$res_view['file'];?>"download><?=$res_view['file'];?></a></p>
	<p><div class=hitlike> 조회수 <?=$res_view['hit'];?>ㅤ좋아요 <?=$res_view['liked'];?></div></p>
</div>

[1] 작성자가 게시글과 함께 업로드한 파일명을 출력한다. 꼭 파일명이 아니어도 상관없긴 하다.
[2] 출력한 파일명에 <a> 태그와 href 속성을 이용해 서버에 저장된 해당 파일의 경로를 링크로 걸어준다.
[3] <a> 태그 내부에 download 속성을 추가해준다.

[4] 특별한 문제가 없다면, 게시글 조회 시 파일 링크를 클릭하면 해당 파일이 다운로드된다.

프로필사진
berry
FE Developer, loves React & better DX
Comments