본문 바로가기

PHP

파일 업로드

앞전에 Spring환경에서는 파일업로드를 해보았으나, php는 처음이라 기록하게 됬다. Spring에서 할때도 남의 도움을 받아한 것이라 잘이해하지 못하여 보다 공부한다는 목적으로도 작성했다.


******php 파일 업로드(HTML코드)

1
2
3
4
5
6
<!-- 데이터 인코딩형 enctype은 꼭 아래처럼 설정해야 합니다 -->
<form enctype='multipart/form-data' action='upload.php' method='post'>
    <!-- input의 name은 $_FILES 배열의 name을 결정합니다 -->
    <input type='file' name='image'>
    <input type="submit" value="파일 전송" />
</form>
cs


html 소스코드는 다음과 같이 작성하라하여 했다. 

<form>태그에서 enctype = "multipart/form-data"라는 애트리뷰트를 반드시 써야한단다. 그렇지 않으면 웹 서버로 데이터를 넘길 때 파일의 경로명만 전송되고 파일 내용이 전송되지 않는다고 한다.  또한 Method 애트리뷰트는 POST로 지정.


간단히 method는 전송 방식, action은 전송 목적지, enctype은 전송되는 데이터 형식을 설정한다.



******php 파일 업로드(PHP코드)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php
 
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["image"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
 
echo "@@@@@@@@@@@@@@@@@@ : ".$imageFileType."<br/>\n";
 
// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
    $check = getimagesize($_FILES["image"]["tmp_name"]);
    if($check !== false) {
        echo "File is an image - " . $check["mime"] . ".";
        $uploadOk = 1;
    } 
    else {
        echo "File is not an image.<br/>\n";
        $uploadOk = 0;
    }
}
 
// Check if file already exists
if (file_exists($target_file)) {
    echo "Sorry, file already exists.<br/>\n";
    $uploadOk = 0;
}
 
// Check file size
if ($_FILES["image"]["size"> 500000) {
    echo "Sorry, your file is too large.<br/>\n";
    $uploadOk = 0;
}
// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg" && $imageFileType != "gif" ) {
    echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.<br/>\n";
    $uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
    echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
else {
    if (move_uploaded_file($_FILES["image"]["tmp_name"], $target_file)) {
        echo "The file "basename$_FILES["image"]["name"]). " has been uploaded.";
    } 
    else {
        echo "Sorry, there was an error uploading your file.<br/>\n";
        echo $_FILES["image"]["error"];
    }
}
 
//임시 디렉토리의 경로를 리턴
$temp_file = tempnam(sys_get_temp_dir(), 'image');
echo "tmp_file : ".$temp_file;
 
?>
cs




PHP코드는 다음과 같다. 
먼저 해당 파일에 대한 정보를 지정하고 담는 변수들 설정. 후에 해당 파일이 실재하는지, 이미 해당 디렉토리에 존재하는지, 크기 체크, 형식 체크 후 실행이다. 마지막줄의 경우는 임시 디렉토리의 경로를 리턴한다해서 썼다. 

******문법

$_FILES['input type file의 이름']['name']
클라이언트 머신에 존재하는 파일의 원래 이름.

$_FILES['input type file의 이름']['type']
브라우저가 이 정보를 제공할 경우에, 파일의 mime 형식. 예를 들면 "image/gif". 그러나 이 mime 형은 PHP 측에서 확인하지 않으므로 이 값을 신용하지 마십시오.

$_FILES['input type file의 이름']['size']
업로드된 파일의 바이트로 표현한 크기.

$_FILES['input type file의 이름']['tmp_name']
서버에 저장된 업로드된 파일의 임시 파일 이름.

$_FILES['input type file의 이름']['error']
파일 업로드에 관련한 에러 코드.

-----------------------------------------------------------------------------------------------

그 결과, 오류난다. 
tmp_file : 뒷부분은 새로고침을 할때마다 image를 제외한 뒷부분은 계속해서 바뀐다.
$target_dir이 잘못된줄 알아 실제 임시 디렉토리 경로를 바꿨으나 똑같다.



분명, php.ini에도 시키는대로 설정했는데.upload_tmp_dir 부분 ;를 지워도 똑같다. 



갑자기 되었다. 

안되는 이유를 계속 찾아보았으나, 공통적으로 나오는 얘기는 업로드 시킬 폴더에 대한 권한문제라고 한다.

그래서 나도 변경해주었다. 


******파일권한


파일타입 : d -> 디렉토리, l -> 링크파일, - -> 일반파일


퍼미션 종류 : r -> 읽기, w -> 쓰기, x -> 실행


3파트로 구성 : 소유자, 그룹, 공개


------------------------------------------------

ex) -rw-r--r--. 1 root root


소유자는 읽기, 쓰기 권한

그룹은 읽기

공개는 읽기


소유자와 소유그룹은 root

------------------------------------------------

* 권한 변경법(r=4, w=2, x=1)


chmod [변경 값] [변경 파일]


* 소유자 변경법


chown [변경할 소유자] [변경 파일]

------------------------------------------------


* s 의미


- 파일의 경우, setuid exec를 의미. 파일에 권한이 있으면 실행 가능. 사용자에게 제한된 루트 권한을 부여하는 방법.


- 디렉토리의 경우, sticky를 의미. 저장소에 있는 파일은 다른 사람이 넣었어도 같은 사람과그룹이 모두 소유하게 된다는 의미.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
 
//업로드한 파일을 저장할 디렉토리
$save_dir = "uploads/";
   
//파일이 HTTP POST 방식을 통해 정상적으로 업로드되었는지 확인한다.
if(is_uploaded_file($_FILES["image"]["tmp_name"]))
{
   echo "업로드한 파일명 : ".$_FILES["image"]["name"] ."<br/>\n";
   echo "업로드한 파일의 크기 : ".$_FILES["image"]["size"] ."<br/>\n";
   echo "업로드한 파일의 MIME Type : ".$_FILES["image"]["type"] ."<br/>\n";
   echo "임시 디렉토리에 저장된 파일명 : ".$_FILES["image"]["tmp_name"] ."<br/>\n";
   
   //파일을 저장할 디렉토리 및 파일명
   $dest = $save_dir .basename($_FILES["image"]["name"]);
   
   //파일을 지정한 디렉토리에 저장
   if(!move_uploaded_file($_FILES["image"]["tmp_name"], $dest)){
        echo "error : ".$_FILES['image']['error']."<br/>\n";
        die("파일을 지정한 디렉토리에 저장하는데 실패했습니다.");
   }
   else{
        echo "드갔다!!!!!!";
   }
}
 
?>
cs


그 결과 잘된다.




************ 
수정화면에서 input type file에 자동으로 이전에 선택한 것이 나타나게 하려고 했으나, 보안상의 문제로 되지 않는다고 함. 

input type=file의 엘리먼트 값은 readonly이다. 스크립트에서 그 값을 지정하거나 변경, 삭제할 수 없다고 한다.












 


'PHP' 카테고리의 다른 글

파일다운로드 - 오류 수정  (0) 2018.11.22
파일 다운로드(header)  (1) 2018.11.21
파일 다운로드  (0) 2018.11.20
rownum 사용  (0) 2018.11.19
form과 post 방식  (0) 2018.11.17