php는 POST로 파일 업로드기능을 제공합니다. RFC-1867 호환 브라우저(넷스케이프 네비게이터 3 이상, 마이크로소프트 인터넷 익스플로러 3+패치나 패치 없이 그 이상 버전을 포함)라면 파일 업로드를 받을 수 있는 기능을 제공합니다.

다음 표의 내용을 php.ini에서 조작할 수 있습니다.

 옵션  의미
 file_uploads

 업로드 기능을 사용할지를 결정합니다. 기본값 On

 upload_tmp_dir  업로드시 임시 저장 될 디렉토리 경로
 upload_max_filesize  허용하는 최대 파일 크기, 기본값 100M
 max_file_uploads  허용하는 최대 업로드 수, 기본값 100개

파일 업로드 폼은 다음 표처럼 작성하되 폼 안에 enctype="multipart/form-data"값이 있는지 확인하여야 합니다. 그렇지 않으면 업로드 기능은 작동하지 않습니다.

 <form enctype="multipart/form-data" action="send_ok.php" method="POST">
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    이 파일을 전송합니다: <input name="userfile" type="file" />
    <input type="submit" value="파일 전송" />
 </form>

method는 post로 정의하며, MAX_FILE_SIZE는 php.ini에 지정된 upload_max_filesize 크기 보다 클 수 는 없습니다. 이 필드는 ini에 지정된 파일크기보다 크면 에러를 표시하는 용도로만 사용되어야 합니다.

보통 하나의 파일을 업로드하면 다음 표의 변수($_FILES['파일명']['name'])를 여러개 가지게 됩니다.

 변수명  의미
 name  클라이언트측 원래 이름
 type  "image/gif"와 같은 파일의 mime형식, 그러나 php에서 확인하지 않으므로 이 값을 무시하여야 합니다.
 size  업로드된 파일의 바이트로 표현한 크기
 tmp_name
 서버에 저장된 업로드된 파일의 임시 파일 이름
 error  파일 업로드에 대한 에러 코드를 표시

파일 업로드는 다음 예제와 같은 과정으로 작성하면 됩니다.

예제 (ex #1

  <form enctype="multipart/form-data" action="" method="POST">
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    이 파일을 전송합니다: <input name="userfile" type="file" />
    <input type="submit" value="파일 전송" />
 </form>

 
<?php
 
// uploads디렉토리에 파일을 업로드합니다.
 
$uploaddir './uploads/'
;
 
$uploadfile $uploaddir basename($_FILES['userfile']['name'
]);

 echo 
'<pre>'
;
 if(
$_POST['MAX_FILE_SIZE'] < $_FILES['userfile']['size'
]){
      echo 
"업로드 파일이 지정된 파일크기보다 큽니다.\n"
;
 } else {
     if((
$_FILES['userfile']['error'] > 0) || ($_FILES['userfile']['size'] <= 0
)){
          echo 
"파일 업로드에 실패하였습니다."
;
     } else {
          
// HTTP post로 전송된 것인지 체크합니다.
          
if(!is_uploaded_file($_FILES['userfile']['tmp_name'
])) {
                echo 
"HTTP로 전송된 파일이 아닙니다."
;
          } else {
                
// move_uploaded_file은 임시 저장되어 있는 파일을 ./uploads 디렉토리로 이동합니다.
                
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile
)) {
                     echo 
"성공적으로 업로드 되었습니다.\n"
;
                } else {
                     echo 
"파일 업로드 실패입니다.\n"
;
                }
          }
     }
 }

 
print_r($_FILES
);

 
/*
 결과:
 성공적으로 업로드 되었습니다.
 Array
 (
    [userfile] => Array
        (
            [name] => config.sys
            [type] => text/plain
            [tmp_name] => /tmp/phpXTtzBW
            [error] => 0
            [size] => 10
        )
 )
 */
 
?> 


파일 업로드가 성공적이면 에러코드는 0을 가집니다. 에러 코드는 다음 표의 상수로 대조해도 됩니다.

 상수명  의미
 UPLOAD_ERR_OK  값: 0; 오류 없이 파일 업로드가 성공했습니다
 UPLOAD_ERR_INI_SIZE 값: 1; 업로드한 파일이 php.ini upload_max_filesize 지시어보다 큽니다
 UPLOAD_ERR_FORM_SIZE 
값: 2; 업로드한 파일이 HTML 폼에서 지정한 MAX_FILE_SIZE 보다 큽니다. 
 UPLOAD_ERR_PARTIAL 
값: 3; 파일이 일부분만 전송되었습니다
 UPLOAD_ERR_NO_FILE  값: 4; 파일이 전송되지 않았습니다
 UPLOAD_ERR_NO_TMP_DIR  값: 6; 임시 폴더가 없습니다. PHP 4.3.10과 PHP 5.0.3에서 추가.
 UPLOAD_ERR_CANT_WRITE  값: 7; 디스크에 파일 쓰기를 실패했습니다. PHP 5.1.0에서 추가
 UPLOAD_ERR_EXTENSION  값: 8; 확장에 의해 파일 업로드가 중지되었습니다. PHP 5.2.0에서 추가.

파일 이름을 서버에 그대로 저장하는 것도 보안상 상당한 위험이 있으므로 md5로 암호화해서 저장하고, 디비에 원래 이름을 저장하도록 합니다.

예제 (ex #2

   <form enctype="multipart/form-data" action="" method="POST">
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    이 파일을 전송합니다: <input name="userfile" type="file" />
    <input type="submit" value="파일 전송" />
 </form>

 
<?php
 
function file_errmsg($code
){
     switch(
$code
){
         case(
UPLOAD_ERR_INI_SIZE
):
         return 
"업로드한 파일이 php.ini upload_max_filesize보다 큽니다."
;
     case(
UPLOAD_ERR_FORM_SIZE
):
         return 
"업로드한 파일이 MAX_FILE_SIZE 보다 큽니다. "
;
     case(
UPLOAD_ERR_PARTIAL
):
         return 
"파일이 일부분만 전송되었습니다. 다시 시도해 주십시요."
;
     case(
UPLOAD_ERR_NO_FILE
):
         return 
"파일이 전송되지 않았습니다."
;
     case(
UPLOAD_ERR_NO_TMP_DIR
):
         return 
"임시 폴더가 없습니다."
;
     case(
UPLOAD_ERR_CANT_WRITE
):
         return 
"디스크에 파일 쓰기를 실패했습니다. 다시 시도해 주십시요."
;
     default:
         return 
"확장에 의해 파일 업로드가 중지되었습니다."
;
     }
 }

 
// 서버에 저장될 디렉토리이름
 
$uploaddir './uploads/'
;
 
// 서버에 저장될 파일이름
 
$filename basename($_FILES['userfile']['name'
]);
 
$md5filename $uploaddir md5("habony_".$filename
);
 
$ext array_pop(explode(".","$filename"
);

 echo 
'<pre>'
;
 if(
$_FILES['userfile']['error'] === UPLOAD_ERR_OK
) {
      if(
strtolower($ext) == "php"
) {
           echo 
"확장자 php파일은 업로드 하실수 없습니다."
;
      }
      else if(
$_FILES['userfile']['size'] <= 0
){
          echo 
"파일 업로드에 실패하였습니다."
;
      } else {
          
// HTTP post로 전송된 것인지 체크합니다.
          
if(!is_uploaded_file($_FILES['userfile']['tmp_name'
])) {
               echo 
"HTTP로 전송된 파일이 아닙니다."
;
          } else {
               
// move_uploaded_file은 임시 저장되어 있는 파일을 ./uploads 디렉토리로 이동합니다.
               
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $md5filename
)) {
                    echo 
"성공적으로 업로드 되었습니다.\n"
;
               } else {
                    echo 
"파일 업로드 실패입니다.\n"
;
               }
               
mysql_query("insert into $db values  ('','$filename')"
);
          }
      }
 } else {
      echo 
file_errmsg($_FILES['userfile']['error'
]);
 }

 
print_r($_FILES
);

 
/*
 결과:
 성공적으로 업로드 되었습니다.
 Array
 (
    [userfile] => Array
        (
            [name] => config.sys
            [type] => text/plain
            [tmp_name] => /tmp/phpXTtzBW
            [error] => 0
            [size] => 10
        )
 )
 */
 
?>

블로그 이미지

하보니

하보니와 함께하는 phP 초보

댓글을 달아 주세요