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 파일에 추가한 값들이 제대로 넘어오는지
하나씩 천천히 확인해가면서 하시는 게 좋을 듯합니다.
고맙습니다.
감사합니다 덕분에 잘 해결하였습니다