멀티 업로드 구현 질문

Ajax를 이용해서 멀티업로드를 구현하려고 하는데 생각대로 되지 않아서 도움이 필요해서 질문 드립니다

1. javascript 소스(Ajax 사용한 멀티

<script type="text/javascript">
    jQuery(document).ready(function(){
        jQuery("#set_explanation_upfile").on("change", function(e) {
            e.preventDefault;

            var formData = new FormData();
            var files_data = jQuery('input[name=set_explanation_upfile');
            var code = document.getElementById("code").value;

            formData.append('set_explanation_upfile', jQuery(files_data)[0].files[0]);

            // 1. 에러 발생하는 코드
            formData.append('set_explanation_upfile', jQuery(files_data)[1].files[0]); // 에러 발생

            // 2. 에러가 발생해서 다르게 변형시킨 코드
            formData.append('set_explanation_upfile', jQuery(files_data)[0].files[1]); // 2번째 파일 인식됨
            formData.append('action', 'set_explanation');  
            formData.append('code', code);

            jQuery.ajax({
                type: 'POST',
                url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
                data: formData,
                contentType: false,
                processData: false,
                success: function(response){
                    set_explanation = response['url']
                    ex_set_explanation = response['file']
                    console.log(set_explanation);
                    console.log(ex_set_explanation);
                }
            });
        });
    });
</script>

 

2. function.php

function set_explanation() {
	$current_user = wp_get_current_user();
	$user_login = $current_user->user_login;
	$test_code = $_POST['code'];
	global $wpdb;

	if(!function_exists('wp_handle_upload')){
		require_once(ABSPATH . 'wp-admin/includes/file.php');
	}

	// multiple을 이용하여 2개 이상의 파일(예제는 2개만 하기로 함)
	$uploadedfile = $_FILES['set_explanation_upfile'];

	// 배열처럼 받은 파일을 foreach 함수를 사용하여 wp_handle_upload를 배열의 횟수만큼 실행
	foreach ($uploadedfile as $key => $value) {
		$movefile = wp_handle_upload($uploadedfile, array('test_form' => false));
	}

	if($movefile && ! isset($movefile['error'])){

	}
	else{
		echo $movefile['error'];
	}

	$uploadedfile = $movefile['file'];
	$uploadedfileURL = $movefile['url'];
	$JsonData = array('file' => $uploadedfile, 'url' => $uploadedfileURL);

	wp_send_json($JsonData);
}
add_action('wp_ajax_set_explanation', 'set_explanation'); //logged in.

 

갑작스럽게 멀티 업로드를 구현하게 되어 구글링을 통해 검색하니 기존의 Ajax를 이용한 업로드에 추가하는 방식으로 되어 있어서

예제를 보고 그대로 따라했지만 에러가 발생되었습니다. (첫번째 소스 1.번)

그래서 그 밑으로 바꾸니깐 input file multiple의 2번째 파일이 인식이 되었습니다.

그런데 문제는 인식이 되고 업로드까지 되었는데 그 전의 파일들은 업로드가 안 됩니다.

예) 파일1.jpg / 파일2.jpg 2개를 클릭하고 업로드 했을 때 파일1.jpg는 업로드가 안되고 파일2.jpg는 업로드가 됩니다. 한마디로 첫번째껄 받아오지 못합니다.

만약에

formData.append('set_explanation_upfile', jQuery(files_data)[0].files[2]);

소스를 추가하고 파일1.jpg / 파일2.jpg / 파일3.jpg 이렇게 할 경우에는 파일3.jpg (제일 마지막에 있는 파일)만 업로드가 되어집니다.

이걸 어떻게 해결할지 몰라서 몇시간째 고민하고 있습니다. 부탁드립니다 ㅠ

워드프레스 에러 기술지원 서비스 전문가에게 맡기세요
워드프레스 에러 기술지원 서비스 전문가에게 맡기세요
  • 안녕하세요~^^

    적용하신 HTML 코드는 어떻게 되시는지요?

    에러는 어떤 에러가 표시되시는지요?

    input 태그의 name을 배열로 설정해주셨는지요?

    <input type="file" id="set_explanation_upfile" name="set_explanation_upfile[]" multiple>

    위의 코드처럼 적용해주셨는지 확인해주시겠어요?

    고맙습니다.

  • 현재 적용한 HTML 코드입니다

    name에 배열이 없었는데 배열을 추가했습니다

    <input type="file" class="" multiple="multiple" name="set_explanation_upfile[]" id="set_explanation_upfile">

     

    그리고 위의 코드는 이렇게 적용했습니다

            jQuery("#set_explanation_upfile").on("change", function(e) {
                e.preventDefault;
    
                var formData = new FormData();
                var files_data = jQuery('input[name=set_explanation_upfile');
                var code = document.getElementById("code").value;
    
                formData.append('set_explanation_upfile', jQuery(files_data)[0].files[0]);
                formData.append('set_explanation_upfile', jQuery(files_data)[1].files[0]);
                formData.append('action', 'set_explanation');  
                formData.append('code', code);
    
                jQuery.ajax({
                    type: 'POST',
                    url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
                    data: formData,
                    contentType: false,
                    processData: false,
                    success: function(response){
                        set_explanation = response['url']
                        ex_set_explanation = response['file']
                        console.log(set_explanation);
                        console.log(ex_set_explanation);
                    }
                });
            })
    

     

    해당 에러 내용입니다

    Uncaught TypeError: Cannot read property 'files' of undefined

     

    위의 코드가 name 지정이 잘못 된거 같아서 변경했습니다

    var files_data = jQuery('input[name=set_explanation_upfile]');

    의 코드를 밑으로 수정

    var files_data = jQuery('input[name=set_explanation_upfile[]]');

     

    해당 에러 내용입니다

    Uncaught Error: Syntax error, unrecognized expression: input[name=set_explanation_upfile[]]

     

  • 올려주신 코드 중에서 아래의 코드의 값은 어디서 가져오시는지요?

    var code = document.getElementById("code").value;

    또, 실제로 console.log()로 jQuery(files_data)를 확인해보면 files 값이 없습니다.

    기존의 코드 대신 아래의 코드를 활용해서 테스트해보시겠어요?

    <script type="text/javascript">
    	jQuery(document).ready(function(){
    		jQuery("#set_explanation_upfile").on("change", function(e) {
    			e.preventDefault;
    
    			// ...
    			
    			var my_files = [];
    			for(var i=0; i<jQuery(this).get(0).files.length; ++i){
    				my_files.push(jQuery(this).get(0).files[i]);
    			}
    
    			// ...
    			
    			jQuery.ajax({
    				type: 'POST',
    				url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
    				data: formData,
    				contentType: false,
    				processData: false,
    				success: function(response){
    					set_explanation = response['url']
    					ex_set_explanation = response['file']
    					console.log(set_explanation);
    					console.log(ex_set_explanation);
    				}
    			});
    		});
    	});
    </script>

     

  • var code는 실질적으로 업로드랑 관계없는 소스이고 DB에 값을 저장하가 위한 변수값입니다.

    var file_Data의 값이 재대로 안 들어가진 것을 확인해서 name을 사용하니깐 문법적인 오류가 생겨서 ID를 지정하는 형식으로 하였습니다.

    var files_data = jQuery('#set_explanation_upfile');

    그 후 적어주신 코드를 사용하고 log를 찍어보니 var my_files에

    [File(1324837), File(1221372)]

    이런 식으로 들어가는것을 확인할 수 있었습니다.

    그럼 Ajax로 보낼 때 Hook를 선언하고 formdata를 선언할 때

    formData.append('set_explanation_upfile', my_files);
    formData.append('action', 'set_explanation');  
    formData.append('code', code);

    이런 식으로 선언하는 것이 맞는건가요? 

    위와  같이 선언하고 실행하니 function.php에서 받질 못하는거 같았습니다.

  • formdata 쪽에는 올려주신 코드처럼 적용해주시면 됩니다.

    실제 테스트해보니 set_explanation_upfile 쪽도 배열로 넘겨주셔야 할 듯합니다.

    script 코드를 기존의 코드 대신 아래의 코드로 테스트해보시겠어요?

    <script type="text/javascript">
    jQuery(document).ready(function(e){
    	jQuery("#set_explanation_upfile").on("change", function(e){
    		var form_data = new FormData();
    		for(var i=0; i<jQuery(this).get(0).files.length; i++){
    			form_data.append("set_explanation_upfile[]", document.getElementById('set_explanation_upfile').files[i]);
    		}
    		
    		form_data.append('action', 'set_explanation');
    		
    		jQuery.ajax({
    			type: 'POST',
    			url: '<?php echo admin_url( 'admin-ajax.php' )?>',
    			data: form_data,
    			contentType: false,
    			processData: false,
    			success: function(response){
    				console.log(response);
    				set_explanation = response['url']
    				ex_set_explanation = response['file']
    				console.log(set_explanation);
    				console.log(ex_set_explanation);
    			}
    		});
    	});
    });
    </script>

    아래의 링크도 참고해보시겠어요?

    https://www.roytuts.com/ajax-multiple-files-upload-using-php-jquery

    고맙습니다.

  • 우선 제가 정리가 필요한 것 같아서 이렇게 적었습니다

    1. javascript Ajax 멀티 업로드 소스

    <script type="text/javascript">
        jQuery(document).ready(function(){
            jQuery("#set_explanation_upfile").on("change", function(e) {
                e.preventDefault;
    
                var formData = new FormData();
                var code = document.getElementById("code").value;
    
                for(var i=0;i<jQuery(this).get(0).files.length;i++) {
                    formData.append("set_explanation_upfile[]", document.getElementById('set_explanation_upfile').files[i]);
                }
    
                formData.append('action', 'set_explanation');  
                formData.append('code', code);
    
                jQuery.ajax({
                    type: 'POST',
                    url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
                    data: formData,
                    contentType: false,
                    processData: false,
                    success: function(response){
                        console.log(response);
                        set_explanation = response['url']
                        ex_set_explanation = response['file']
                        console.log(set_explanation);
                        console.log(ex_set_explanation);
                    }
                });
            });
        });
    </script>

     

    2. HTML 멀티 업로드 폼

    <input type="file" class="" multiple="multiple" name="set_explanation_upfile[]" id="set_explanation_upfile">

     

    3. function.php Hook 소스

    function set_explanation() {
    	$current_user = wp_get_current_user();
    	$user_login = $current_user->user_login;
    	$test_code = $_POST['code'];
    	global $wpdb;
    
    	if(!function_exists('wp_handle_upload')){
    		require_once(ABSPATH . 'wp-admin/includes/file.php');
    	}
    	// 업로드 방식이 배열이라 $_FILES['배열']로 받음
    	$uploadedfile = $_FILES['set_explanation_upfile[]'];
    
    	// 배열의 크기만큼 업로드 반복
    	foreach ($uploadedfile as $key => $value) {
    		$movefile = wp_handle_upload($uploadedfile, array('test_form' => false));
    	}
    
    	if($movefile && ! isset($movefile['error'])){
    
    	}
    	else{
    		echo $movefile['error'];
    	}
    
    	// 이 부분은 차후 수정할 예정
    	$uploadedfile = $movefile['file'];
    	$uploadedfileURL = $movefile['url'];
    	$JsonData = array('file' => $uploadedfile, 'url' => $uploadedfileURL);
    
    	wp_send_json($JsonData);
    }
    add_action('wp_ajax_set_explanation', 'set_explanation'); //logged in.

     

    현재 멀티업로드를 구성하는 3가지 소스입니다. 

    오류는 안 일어나고 console.log(response); 가 출력을 되는 것을 확인하였습니다.

    그런데 업로드는 안 되는 것을 보아 function.php 에서 

    // 업로드 방식이 배열이라 $_FILES['배열']로 받음
    $uploadedfile = $_FILES['set_explanation_upfile[]'];
    
    // 배열의 크기만큼 업로드 반복
    foreach ($uploadedfile as $key => $value) {
    	$movefile = wp_handle_upload($uploadedfile, array('test_form' => false));
    }

    이 부분이 잘못된 것 같습니다.

    wp_handle_upload()를 반복문 안에서 업로드 파일을 저런식으로 선언하는 것이 틀린 것인가요?

  • functions.php 파일 쪽 코드만 수정해주시면 될 듯합니다.

    올려주신 코드 중에서 아래의 코드 대신

    // 업로드 방식이 배열이라 $_FILES['배열']로 받음
    $uploadedfile = $_FILES['set_explanation_upfile[]'];
    
    // 배열의 크기만큼 업로드 반복
    foreach ($uploadedfile as $key => $value) {
    	$movefile = wp_handle_upload($uploadedfile, array('test_form' => false));
    }

    아래의 코드처럼 적용해보시겠어요?

    $uploadedfile = $_FILES['set_explanation_upfile'];
    
    // 배열의 크기만큼 업로드 반복
    foreach($uploadedfile['name'] as $key=>$value){
    	if($uploadedfile['name'][$key]){
    		$movefile = array(
    			'name'     => $uploadedfile['name'][$key],
    			'type'     => $uploadedfile['type'][$key],
    			'tmp_name' => $uploadedfile['tmp_name'][$key],
    			'error'    => $uploadedfile['error'][$key],
    			'size'     => $uploadedfile['size'][$key]
    		);
    		wp_handle_upload($movefile, array('test_form'=>false));
    	}
    }

    테마 쪽 functions.php 파일에 추가한 값들이 제대로 넘어오는지

    하나씩 천천히 확인해가면서 하시는 게 좋을 듯합니다.

    고맙습니다.

  • 감사합니다 덕분에 잘 해결하였습니다

워드프레스 에러 기술지원 서비스 전문가에게 맡기세요