Ajax로 파일을 업로드하고 싶습니다

 Ajax로 excel을 업로드한 뒤에 파일을 읽어서 DB에 넣어주고 싶습니다.

구글에서 돌아다니는 소스를 통해서 소스를 짜고 있는데 문제는 제가 하고 있는게 맞는건지 확신이 없어서

소스를 검토+잘못된 것은 첨삭을 부탁드리려고 글을 올리게 되었습니다

Ajax로 보내는 소스입니다 id="upfile"은 <input type="file" id="upfile"> 입니다

		$("#upfile").off().on('change', function() {		
			var data = $("#upfile").val();

			console.log("시작");
			console.log(data);
			console.log("종료");
			$.post(ajax_object.ajax_url, {     //ajax object
				action : 'set_excel',           //hook name
				data : data,
				processData: false,
				contentType: false
			}, function(data) {
				console.log(data);
				alert(data);
			});
		});

 

function.php 에서 받는 소스입니다

	$upfile_name = $_FILES['upfile']['name']; // 파일이름
	$upfile_type = $_FILES['upfile']['type']; // 확장자
	$upfile_size = $_FILES['upfile']['size']; // 파일크기
	$upfile_tmp  = $_FILES['upfile']['tmp_name']; // 임시 디렉토리에 저장된 파일명
	$uploadfile = $uploaddir . $_FILES['userfile']['name'];

(인터넷에서 전부다 excel파일을 이렇게 받던데 ajax로 하려고 하니깐 안되더군요)

워드프레스 자체가 플러그인을 사용해서 업로드가 가능하지만

excel 파일을 업로드하면서 DB에 Import하는 플러그인을 못 찾겠더군요

그래서 직접적으로 소스를 만지면서 기능을 구현하려고 하여 이렇게 질문하게 되었습니다

워드프레스 에러 기술지원 서비스 전문가에게 맡기세요
워드프레스 에러 기술지원 서비스 전문가에게 맡기세요
  • wp_handle_upload 함수를 사용하시려면

    Ajax 파일 데이터를 넘겨줄 때 실제 파일 형식에 맞춰서 넘겨주셔야 합니다.

    워드프레스에서는 $("#upfile1") 코드 대신 jQuery("#upfile1") 이런 식으로 적용해주셔야 합니다.

     

    예제 코드를 만들어 봤습니다.

    아래의 코드를 활용해보시겠어요?

    <input type="file" id="upfile1" name="upfile1" accept="image/*"/>
    <script>
    jQuery(document).ready(function() {
        jQuery('#upfile1').on('change', function(e){
            e.preventDefault;
    
            var formData = new FormData();
            var files_data = jQuery('#upfile1');
    
    		formData.append('upfile1', jQuery(files_data)[0].files[0]);
            formData.append('action', 'set_excel');  
    
            jQuery.ajax({
                type: 'POST',
                url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
                data: formData,
                contentType: false,
                processData: false,
                success: function(response){
    				alert(response);
                }
            });
        });
    });
    </script>

     

    테마 쪽 functions.php 파일에는 아래의 코드를 활용해보세요.

    add_action('wp_ajax_set_excel', 'set_excel');
    add_action('wp_ajax_nopriv_set_excel', 'set_excel');
    function set_excel(){
    	if(!function_exists('wp_handle_upload')){
    		require_once(ABSPATH . 'wp-admin/includes/file.php');
    	}
    
    	$uploadedfile = $_FILES['upfile1'];
    	$movefile = wp_handle_upload($uploadedfile, array('test_form' => false));
    	
    	if($movefile && ! isset($movefile['error'])){
    		echo "업로드 되었습니다.";
    	}
    	else{
    		echo $movefile['error'];
    	}
    	exit;
    }

    고맙습니다.

  • 안녕하세요~^^

    워드프레스의 wp_handle_upload() 함수를 사용해보시겠어요?

    아래 예제 코드도 참고해주세요.

    if ( ! function_exists( 'wp_handle_upload' ) ) {
        require_once( ABSPATH . 'wp-admin/includes/file.php' );
    }
    
    $uploadedfile = $_FILES['file'];
    
    $upload_overrides = array( 'test_form' => false );
    
    $movefile = wp_handle_upload( $uploadedfile, $upload_overrides );
    
    if ( $movefile && ! isset( $movefile['error'] ) ) {
        echo "File is valid, and was successfully uploaded.\n";
        var_dump( $movefile );
    } else {
        /**
         * Error generated by _wp_handle_upload()
         * @see _wp_handle_upload() in wp-admin/includes/file.php
         */
        echo $movefile['error'];
    }

    위의 예제 코드에서 $_FILES['file']; 이 부분은

    실제로 <input type="file" name="file"> 코드에서 input의 name과 일치시켜 주시면 됩니다.

     

    form 태그에 enctype="multipart/form-data" 속성이 있는지 확인해보세요.

    <form enctype="multipart/form-data"> 이런 형식입니다.

    해당 속성 없이는 파일이 전송되지 않습니다.

     

    추가로 PHP의 파일 업로드 방식과 스택 오버플로우에 올라온 질문을 참고해보시면 도움이 되실 듯합니다.

    http://php.net/manual/kr/features.file-upload.post-method.php
    https://wordpress.stackexchange.com/questions/198781/wordpress-ajax-file-upload-frontend

    고맙습니다.

  • 예제를 봐도 잘 모르는 이유는 Form 태그의 Action 값 때문에 그렇습니다

    워드프레스는 form에서 데이터를 보낼때 어디 ~.php에 데이터를 보내세요

    라는게 안되는걸로 알고 있습니다. 실제로 몇몇 실험 해보고 안됬었구요

    그래서 찾은게 Ajax를 이용하여 Action의 function.php의 함수를 실행하고 거기로 데이터를 보내는 식으로 했는데

    파일 업로드는 이런식으로 하면 안되는건가요?

  • 올려드린 사이트는 참고용으로 올려드렸습니다.

    말씀하신 것처럼 functions.php 쪽에 추가하신 Ajax Action으로 하셔도 됩니다.

    functions.php 쪽에 추가하신 코드에

    실제 업로드는 워드프레스 내장 함수인 wp_handle_upload() 함수를 사용해보시겠어요?

    고맙습니다.

  • 안녕하세요 지금 3일째 붙잡고 있는데 잘 안되고 있습니다.

    정리를 하고 싶어서 질문을 올립니다

    1. 올려주신 예제를 이런 식으로 쓰는 것이 맞는건지 확인하고 싶습니다

    function set_excel() {
    	if ( ! function_exists( 'wp_handle_upload' ) ) {
    	    require_once( ABSPATH . 'wp-admin/includes/file.php' );
    	}
    
    	$uploadedfile = $_FILES['upfile1'];
    //	$uploadedfile = $_POST['data'];
    
    //	print_r($uploadedfile);
    
    	$upload_overrides = array( 'test_form' => false );
    
    	$movefile = wp_handle_upload( $uploadedfile, $upload_overrides );
    
    	if ( $movefile && ! isset( $movefile['error'] ) ) {
    	    echo "File is valid, and was successfully uploaded.\n";
    	    var_dump( $movefile );
    	} else {
    	    /**
    	     * Error generated by _wp_handle_upload()
    	     * @see _wp_handle_upload() in wp-admin/includes/file.php
    	     */
    	    echo $movefile['error'];
    	}
    }
    add_action('wp_ajax_set_excel', 'set_excel'); //logged in.
    add_action('wp_ajax_nopriv_set_excel', 'set_excel'); //not logged in.

    ajax를 통해 파일을 업로드 하기 위해서 함수를 지정하여서 예제소스를 넣었습니다.

     

    2. jQuery를 이용하여 Ajax를 사용해 파일을 업로드 하려고 합니다.(해당 jQuery는 custom.js에서 사용하고 있습니다)

    $("#upfile1").off().on('change', function() {
    			var file_data = $("#upfile1").prop("files")[0];   
    			var form_data = new FormData();
    			form_data.append("files", file_data);
    
    //			var data = $("#upfile").val();   
    
    		    console.log("시작");
    			console.log(form_data.get("files"));
    			console.log("종료");
    		   	$.post(ajax_object.ajax_url, {     //ajax object
    				action : 'set_excel',           //hook name
    				data : form_data.get("files"),
    				processData: false,
        			contentType: false,
        			type: 'POST',
    				mimeType: 'multipart/form-data'
    			}, function(data) {
    				console.log(data);
    				alert(data);
    			});
    		});

    해당 소스는 file이 들어왔을 때 자동적으로 실행해서 데이터를 업로드 하려고 구현할 예정입니다

    console.log(form_data.get(files)) 을 찍을 경우 해당 로그가 출력이 됩니다

    File(158) {name: "mycsv.csv", lastModified: 1532003962671, lastModifiedDate: Thu Jul 19 2018 21:39:22 GMT+0900 (한국 표준시), webkitRelativePath: "", size: 158, …}

    소스를 보시면 아시다시피 해당 데이터를 function.php -> set_excel()로 데이터를 보내고 있습니다.

    그런데 이 데이터가 형식에 맞게 보내는건지 잘 모르겠습니다

    (Ajax가 실행되면 출력되는 해당 오류)

    Uncaught TypeError: Illegal invocation
        at e (jquery.js?ver=1.12.4:4)
        at dc (jquery.js?ver=1.12.4:4)
        at dc (jquery.js?ver=1.12.4:4)
        at Function.n.param (jquery.js?ver=1.12.4:4)
        at Function.ajax (jquery.js?ver=1.12.4:4)
        at Function.n.(:8080/wordpress/%eb%ac%b8%ec%a0%9c%ec%b6%9c%ec%a0%9c/anonymous function) [as post] (http://localhost:8080/wordpress/wp-includes/js/jquery/jquery.js?ver=1.12.4:4:23175)
        at HTMLInputElement.<anonymous> (custom.js?ver=4.9.7:243)
        at HTMLInputElement.dispatch (jquery.js?ver=1.12.4:3)
        at HTMLInputElement.r.handle (jquery.js?ver=1.12.4:3)

     

    3. formdata의 값을 재대로 쓰고 있는지 확인하고 싶습니다.

    위 소스를 보시면 눈치 채실수도 있지만 formdata는 enctype="multipart/form-data"를 자동으로 지정해준다고 하여 Form을 따로 지정을 안하고

    file에 지정된 ID, Name 값만 가지고 왔습니다. 그래도 오류가 생기길래 값을 보낼때 mimeType : 'multipart/form-data' 로 설정하였으나 아무런 효과가 없었습니다

     

    4. 올려주신 wp_handle_upload 함수가 테마에 따라 적용이 안 될수 있는지 궁금합니다.

    지금 제가 사용하는 테마의 이름은 Study Circle 입니다 wp_handle_upload의 관련된 함수가 지정이 안되서

    혹시 출력이 안되는게 아닐까 생각도 들고 있습니다. 그런데 이걸 확인해보고 싶어도 어떻게 확인하는지 잘 모르겠습니다.

     

    더 궁금한게 있지만 우선 가장 중요한것은 이 4가지인거 같습니다.

    이렇게 되면 파일이 미디어 라이브러리에 들어가야 된다고 생각하며 코드를 짠건데 자꾸 막혀있습니다.

  • 감사합니다 덕분에 무사히 잘 해겼습니다

    그런데 죄송하지만 추가적인 질문좀 있습니다.

    이 파일을 업로드 했을 때 경로가 필요합니다.

    wp_upload_dir()를 사용해보니 제 로컬서버의 절대경로가 나오는데 제가 필요한건 동적인 파일경로가 필요합니다.

    예를 들어 미디어라이브러리에서 7월에 저장되면 "http://localhost:XXXX/wordpress/upload/2018/07/FileName.확장자"

    9월에 저장되면 "http://localhost:XXXX/wordpress/upload/2018/09/FileName.확장자" 이런 식으로 경로를 필요합니다

    이러기 위해서는 어떤 식으로 값을 가져오나요?

  • 안녕하세요.

    별 다른 설정을 하지 않으셨다면 wp_upload_dir() 함수를 사용하시면

    /wp-content/uploads/년도/월 경로를 표시합니다.

    년도와 월은 현재 시간을 기준으로 설정됩니다.

    만약 wp_upload_dir('2018/09') 처럼 사용하시면

    /wp-content/uploads/2018/09로 표시됩니다.

     

    워드프레스 관리자 -> 외모 -> 테마 편집기 페이지에서 functions.php 파일 하단에

    아래의 코드를 추가해서 확인해보실 수 있습니다.

    add_action('init', 'my_init');
    function my_init(){
    	print_r(wp_upload_dir());
    	echo '<br>';
    	print_r(wp_upload_dir('2018/09'));
    }

    고맙습니다.

좋은 정보와 인맥을 동시에, 워드프레스 사용자 단톡방 참여하기