웹&컴퓨팅

php 파일 업, 다운로드 php

x2chi 2007. 10. 11. 19:35
반응형
php 파일 업, 다운로드 php

2005/12/26 11:49

http://blog.naver.com/in1n4/10000463077

1. 업로드
  ●업로드된 파일은 microtime 함수로 파일이름을 바꾼다
     참고 : ⓐ 스크립트가 실행될 염려가 없다.
            ⓑ <img src="0.1234545345"> 같이 확장자가 꼭 gif, jpg가 아니더라도 이미지가
               이미지가 보이므로 이미지파일을 꼭 예외로 할필요는 없다.
  ●is_uploaded_file()과  move_uploaded_file()을 사용한다.
     참고 : ⓐ php매뉴얼에 사용된 함수들이다.
            ⓑ move_uploaded_file()은 파일을 이동시키는 명령어이기때문에 파일을 카피하고
               임시파일을 지우는 명령보다 비용이 싸다.

2. 다운로드
  ●파일이름을 원상복구 시켜서 다운로드 시킨다. (원본파일이름은 디비에 저장되어있다)
  ●download.php 파일을 만들어 파일을 다운로드 시켜준다.
     참고 : ⓐ <a href=download.php?file_name=파일이름>파일받기</a> 이런형태로 다운로드 링크가 된다.
            ⓑ 단 위의 방법에는 한가지 문제점이 있다. 주소창에 [download.php?file_name=../db/config.php]
               이런식으로 직접 쓰는경우에 보안에 중요한 파일이 유출될수 있다.              
            ⓒ 이를 해결하기 위해 "파일이름"이 정해준 디렉토리 안의 파일인지 검사하게 한다.
               (단순히 파일이름에 ".." 또는 "/"또는 "\"가 들어가지 못하게 하면된다)


3. 다운로드 링크는...
<a href="download.php?file_name=진짜파일이름&file_micro=마이크로타임으로변환된이름">다운로드</a>
이렇게 해주시면 됩니다.


downloadn.php 파일
<?
require_once "lib.php";

// 접근경로 확인
if (!eregi($_SERVER['HTTP_HOST'], $_SERVER['HTTP_REFERER'])) Error("외부에서는 다운로드 받으실수 없습니다.");


// 다운로드 방식을 구한다.
$ext = array_pop(explode(".", $_GET['file_name']));

if ($ext=="avi" || $ext=="asf")         $file_type = "video/x-msvideo";
else if ($ext=="mpg" || $ext=="mpeg")   $file_type = "video/mpeg";
else if ($ext=="jpg" || $ext=="jpeg")   $file_type = "image/jpeg";
else if ($ext=="gif")                   $file_type = "image/gif";
else if ($ext=="png")                   $file_type = "image/png";
else if ($ext=="txt")                   $file_type = "text/plain";
else if ($ext=="zip")                   $file_type = "application/x-zip-compressed";

// 실제로 다운로드 받는다.
$ret = download_file( $_GET['file_name'], $_GET['file_micro'], "여기에 파일이 있는 디렉토리를 쓴다.", $file_type);

if( $ret == 1 ) Error("지정하신 파일이 없습니다.");
if( $ret == 2 ) Error("접근불가능 파일입니다. 정상 접근 하시기 바랍니다.");
?>
  

lib.php 파일
<?
//=========================================================================================
//  파일 업로드 함수
//
//  파라미터
//    $upload_dir     : 업로드 드렉토리
//    $tmp_file       : 서버로 업로드된 임시 파일
//    $file_name_plus : 관리를 위해 파일앞에 붙여주는 문자열
//
//  리턴값
//    파일저장에 성공햇을겨우 바꾸어진 파일 이름을 넘긴다.
//    실패할경우 널문자를 넘긴다.
//=========================================================================================
function upload_file($upload_dir, $tmp_file, $file_name_plus="" )
{
        // 파일이름을 시간으로 바꿔서 php등으 스크립트 언어가 실행되지 못하게한다.
        $new_file_name = microtime();


        // 파일이름이 겹친다면 (마이크로 타임으로 바꾸었기 때문에 이럴일은 거의 없다.)
        // 파일 확장자 전에 '_i' 를  붙인다. (i는 임의의숫자)
        $old_new_file_name = $new_file_name;
        for( $i=0; file_exists( $upload_dir.$new_file_name ); $i++ )
                $new_file_name = $old_new_file_name."_".$i;


        // 관리를 쉽게하기위해 file_name_plus를 앞에 달아준다.
        $new_file_name = $file_name_plus.$new_file_name;

        //빈칸을 없앤다.
       $new_file_name = str_replace(" ","_", $new_file_name);

        // 임시디렉토리에서 지정디렉토리로 파일을 옴긴다.
        if( is_uploaded_file( $tmp_file ) )
                move_uploaded_file( $tmp_file, $upload_dir.$new_file_name );
        else return "";

        return $new_file_name;
}


//=========================================================================================
//  이름 바꿔 다운로드하기
//
//  파라미터
//    $file_name  : 실제파일이름
//    $file_dir   : 파일의 위치
//    $file_micro : 바뀐 파일 이름명
//    $file_type  : 파일의 다운로드 방식, 비워두면 일반 파일이다.
//                                    - 동영상  : video/mpeg, video/x-msvideo
//                                    - 이미지  : image/jpeg, image/gif, image/png
//                                    - Zip파일 : application/x-zip-compressed
//                                    - txt파일 : text/plain
//  리턴값
//          완료했을 경우 0을 리턴한다.
//          다운로드 파일이 없으면 요청시 1을 리턴한다.
//          해킹시도등 잘못된 파일 요청시 2을 리턴한다.
//=========================================================================================
function download_file($file_name, $file_micro, $file_dir, $file_type )
{
        // 읽어올 파일명에 이상이있는지 검사한다.
        if( !$file_name || !$file_micro || !$file_dir ) return 1;
        if( eregi( "\\\\|\.\.|/", $file_micro ) ) return 2;


        if( file_exists($file_dir.$file_micro) )
        {
                $fp = fopen($file_dir.$file_micro,"r");

                if( $file_type )
                {
                        header("Content-type: $file_type");
                        Header("Content-Length: ".filesize($file_dir.$file_micro));    
                        Header("Content-Disposition: attachment; filename=$file_name");  
                        Header("Content-Transfer-Encoding: binary");
                        header("Expires: 0");
                }
                else
                {
                        if(eregi("(MSIE 5.0|MSIE 5.1|MSIE 5.5|MSIE 6.0)", $HTTP_USER_AGENT))
                        {
                                Header("Content-type: application/octet-stream");
                                Header("Content-Length: ".filesize($file_dir.$file_micro));    
                                Header("Content-Disposition: attachment; filename=$file_name");  
                                Header("Content-Transfer-Encoding: binary");  
                                Header("Expires: 0");  
                        }
                        else
                        {
                                Header("Content-type: file/unknown");    
                                Header("Content-Length: ".filesize($file_dir.$file_micro));
                                Header("Content-Disposition: attachment; filename=$file_name");
                                Header("Content-Description: PHP3 Generated Data");
                                Header("Expires: 0");
                        }
                }


                fpassthru($fp);
                fclose($fp);
        }
        else return 1;
}

//=========================================================================================
//  파일 삭제하기
//
//  파라미터
//    $file_name  : 실제파일이름
//    $file_dir   : 파일의 위치
//
//  리턴값
//          완료했을 경우 0을 리턴한다.
//          삭제할 파일이 없으면 요청시 1을 리턴한다.
//          해킹시도등 잘못된 파일 요청시 2을 리턴한다.
//    파일이 존재하지만 지울수 없는겨우 3을 리턴한다.
//=========================================================================================
function delete_file($file_name, $file_dir )
{
        // 읽어올 파일명에 이상이있는지 검사한다.
        if( !$file_name || !$file_dir ) return 1;
        if( eregi( "\\\\|\.\.|/", $file_name ) ) return 2;

        // 파일이 있나 검사.
        if( !file_exists($file_dir.$file_micro) ) return 1;

        // 있는데 못지웠을 경우
        if( !unlink() ) return 3;

        return 0;
}
?>
반응형

'웹&컴퓨팅' 카테고리의 다른 글

셀렉트박스 -> 레이어 변환 스크립트 HTC 버전  (1) 2007.10.17
검색엔진최적화(SEO) - 메타태그(META TAG)의 속성정리  (0) 2007.10.12
meta  (0) 2007.10.11
스크립트  (0) 2007.10.11
crontab  (1) 2007.08.10