본문으로 바로가기

AjaxFileUpload - 파일 업로드

category 코딩/PHP 2014. 7. 24. 11:39

JQuery의 serialize()/serializeArray() 함수는 input type=file 요소를 직렬화하지 않는다.
이 때문에도 그렇고 비동기 방식으로 처리하고 싶을 때도 아래 AJAX 방식으로 파일 업로드 부분을 구현한다.

서버 설정

파일이 업로드 되어질 디렉토리 권한 설정을 해 주어야 한다.

# vi /usr/local/apache2/conf/httpd.conf +114
User daemon
Group deamon

아파치 데몬을 실행하는 그룹과 유저를 확인, 필요한 경우엔 수정.

# ll
합계 16
drwxr-xr-x. 2 root   root   4096 2014-07-23 16:13 css
drwxrwxr-x. 3 daemon daemon 4096 2014-07-23 17:16 data
drwxr-xr-x. 6 root   root   4096 2014-07-23 17:48 img
drwxr-xr-x. 2 root   root   4096 2014-07-23 15:48 js

파일이 업로드 되어질 디렉토리의 소유자와 권한을 확인.
위에서 확인된 그룹과 유저에 맞게 디렉토리 소유자가 지정되어 있어야 한다.

(수정하려면 # chown daemon.daemon data # chmod 775 data)

소스

http://www.phpletter.com/Demo/AjaxFileUpload-Demo/ 이 주소에서 

AjaxFileUploaderV2.1.zip

이 파일을 다운 받는다.
압축을 풀면 예제와 함께 js 파일이 포함되어 있는데, ajaxfileupload.js, loading.gif 파일만 사용.

<!-- HTML 페이지 -->
<script type="text/javascript" src="<?=WEB_JS_DIR?>/ajaxfileupload.js"></script>
<script type="text/javascript">
function ajaxFileUpload()
{
	$("#loading")
	.ajaxStart(function(){
		$(this).show();
	})
	.ajaxComplete(function(){
		$(this).hide();
	});
	
	var acvid = $("#acvid").val();
	
	$.ajaxFileUpload
	(
		{
			url:'/append_file/ajax_file_upload',
			secureuri:false,
			fileElementId:'fileToUpload',
			dataType: 'json',
			data:{acvid:acvid},
			success: function (data, status)
			{
				if(typeof(data.error) != 'undefined')
				{
					if(data.error != '')
					{
						alert(data.error);
					}else
					{
						alert(data.msg);
						$("#dialog").dialog("close");
					}
				}
			},
			error: function (data, status, e)
			{
				alert(e);
			}
		}
	)
	
	return false;
}
</script>
<img id="loading" src="<?=WEB_IMG_DIR?>/loading.gif" style="display:none;">
<form name="form" action="" method="POST" enctype="multipart/form-data">
    <input type="hidden" id="acvid" name="acvid" value="<?=$acvid?>">
    <div id="dialog_warp" style="width:300px;">
        <input type="file" id="fileToUpload" name="fileToUpload" style="width:300px;" size="30">
    </div>
    <br />
    <button id="buttonUpload" onclick="return ajaxFileUpload();" class="btn01"><!--?=$acvid?-->파일 업로드</button>
</form>
// 받아서 처리하는 PHP 페이지
$error = '';
$msg = '';

$this->load->model('check_model');

$path = $this->input->server('DOCUMENT_ROOT').'/assets/data/'.date('Y_m').'/';
$max_size = 1024*1024*10;
$denyArr= array("PHP","PHP3","HTML","HTM","ASP","C","PL","JS","JSP","INI","INC","EXE","BAT","CHM");

$file_name = @$_FILES['fileToUpload']['name'];
$tmp_name = @$_FILES['fileToUpload']['tmp_name'];
$tmp_ext = strtoupper(end(explode(".",$file_name)));
$content_type = @$_FILES['fileToUpload']['type'];
$tmp_size = @$_FILES['fileToUpload']['size'];
$ren_file_name = date('Ymd_his').".".$tmp_ext;

for($i=0;$i < count($denyArr);$i++) {
    if(strstr(strtoupper(end(explode(".",$file_name))),$denyArr[$i])) {
        $error = strtoupper($tmp_ext).' 확장자는 업로드할수 없습니다.';
    }
}

if(!$tmp_size || $tmp_size > $max_size) $error = ($max_size/1024/1024).'MB 이상은 업로드 할 수 없습니다.';

if (!is_dir($path)) {
    @mkdir($path, 0775);
    @chmod($path, 0775);

    if (!is_dir($path)) $error = '디렉토리 생성에 실패하였습니다.';

    add_index($path);
}

$tmp = explode(".", $file_name);
$extension = $tmp[sizeof($tmp)              -1];

$ren_file_name = $this->Get_Filename($path, $ren_file_name);

if($error != '') {

    if(copy($tmp_name, $path.$ren_file_name)) {

        $attr_model = array(
            'action'		=> 'add',
            'acvid'			=> $this->input->post('acvid'),
            'userid'		=> USERID,
            'ren_file_name'	=> str_replace($_SERVER['DOCUMENT_ROOT'],'',$path).$ren_file_name,	//웹 경로로 변경
            'ori_file_name'	=> str_replace(' ','_',$file_name),
            'file_size'		=> $tmp_size
        );

        $rtn= $this->check_model->append_file_proc($attr_model);
        $msg = '업로드 완료';

    } else {
        
        $error =  '파일 생성 실패';
    
    }
}

unlink($tmp_name);

echo "{";
echo "error: '" . $error . "',\n";
echo "msg: '" . $msg . "'\n";
echo "}";