
// 수정 - 새로운 파일 첨부
const id_attach = document.querySelector("#id_attach")
if (id_attach) {
id_attach.addEventListener("change", () => {
const f = new FormData()
f.append("bcode", params['bcode']) // 게시판 코드
f.append("mode", "file_attach") // 모드 : 파일만 첨부
f.append("idx", params['idx'])
if (id_attach.files[0].size > 40 * 1024 * 1024) {
alert("파일 크기가 40MB보다 큰 파일이 첨부되었습니다.")
id_attach.value = ""
return false
}
ext = getExtensionOfFilename(id_attach.files[0].name)
if (ext == 'exe' || ext == 'php' || ext == 'js') {
alert("첨부할 수 없는 파일을 업로드 하였습나다. (exe, txt, xls, php, js ..)")
id_attach.value = ""
return false
}
f.append("files", id_attach.files[0])
const xhr = new XMLHttpRequest()
xhr.open('post', './pg/board_process.php', true)
xhr.send(f)
xhr.onload = () => {
if (xhr.status = 200) {
alert('통신 성공')
} else if (xhr.status == 404) {
alert('통신 실패')
}
}
})
}
기존에 게시글 작성 부분을 가져와 수정하였습니다. 크게 설명할 부분이 없어서 생략하도록 하겠습니다.
if (id_attach) {
id_attach.addEventListener("change", () => {
const f = new FormData()
f.append("bcode", params['bcode']) // 게시판 코드
f.append("mode", "file_attach") // 모드 : 파일만 첨부
f.append("idx", params['idx'])
if (id_attach.files[0].size > 40 * 1024 * 1024) {
alert("파일 크기가 40MB보다 큰 파일이 첨부되었습니다.")
id_attach.value = ""
return false
}
ext = getExtensionOfFilename(id_attach.files[0].name)
if (ext == 'exe' || ext == 'php' || ext == 'js') {
alert("첨부할 수 없는 파일을 업로드 하였습나다. (exe, txt, xls, php, js ..)")
id_attach.value = ""
return false
}
f.append("files[]", id_attach.files[0])
const xhr = new XMLHttpRequest()
xhr.open('post', './pg/board_process.php', true)
xhr.send(f)
xhr.onload = () => {
if (xhr.status = 200) {
const data = JSON.parse(xhr.responseText)
if (data.result == 'success') {
location.reload()
} else if (data.result == 'empty_files') {
alert('파일이 첨부되지 않았습니다.')
}
} else if (xhr.status == 404) {
alert('통신 실패')
}
}
})
}
원래는 Frontend 부분에서 파일을 저장할 때 files 변수에 저장하려고 했는데 그렇게 하면 방식을 바꿔야 해서 배열로 받기로 하였습니다. 물론 바꾸지 않는다고 해서 안 되는 건 아닙니다. 단지 지금 여태까지 사용해 오던걸 사용하기 위함입니다.
else if ($mode == 'file_attach') {
// 수정에서 개별파일 첨부하기
$file_list_str = '';
if (isset($_FILES["files"])) {
$file_cnt = 1;
$file_list_str = $board->file_attach($_FILES['files'], $file_cnt);
} else {
$arr = ['result' => 'empty_files'];
die(json_encode($arr));
}
$row = $board->view($idx);
if ($row['files'] != '') {
$files = $row['files'] . '?' . $file_list_str;
} else {
$files = $file_list_str;
}
if ($row['downhit'] != '') {
$downs = $row['downhit'] . '?0';
} else {
$downs = '';
}
$board->updateFileList($idx, $files, $downs);
$arr = ['result' => 'success'];
die(json_encode($arr));
}
게시글을 작성할 때 파일을 첨부하지 않을 수도 있기 때문에 비어 있을 때를 대비하였습니다.
기존에 파일이 있거나 다운로드 횟수가 존재하면 그대로 새로운 파일만 '?' 을 추가해 주고 다운로드 횟수 또한 값이 존재하면 거기에 '?0' 을 붙여주었습니다. 값이 비어 있을 때는 그대로 두었습니다.
// 파일 첨부
public function file_attach($files, $file_cnt,)
{
if (sizeof($files["name"]) > 3) {
$arr = ["result" => "file_upload_count_exceed"];
die(json_encode($arr));
}
// 다중 파일 첨부
$tmp_arr = [];
foreach ($files["name"] as $key => $val) {
$full_str = "";
$tmparr = explode(".", $files["name"][$key]);
$ext = end($tmparr);
$not_allowed_file = ["exe"];
if (in_array($ext, $not_allowed_file)) {
$arr = ["result" => "not_allowed_file"];
die(json_encode($arr));
}
$flag = rand(1000, 9999);
$filename = 'a' . date('YmdHis') . $flag . '.' . $ext;
$file_ori = $files["name"][$key]; // 원본 이미지
copy($files["tmp_name"][$key], BOARD_DIR . '/' . $filename); // 이미지 파일 저장
$full_str = $filename . '|' . $file_ori; // 원본 이미지 이름과 바뀐 이미지 이름
$tmp_arr[] = $full_str;
}
return implode("?", $tmp_arr);
}
기존에 사용하는 방식을 바꾸었습니다. 원래는 다중으로 파일을 업로드 할 수 있었는데, 하나씩 첨부하는 거로 수정하였습니다. 수정하는 부분에서 파일을 업로드 할때 이미 2개의 파일이 존재할 때 2개 이상 파일을 올리게 되면 파일 개수를 넘어섭니다. 그러면 또 거기서 1개를 받든 2개를 받든 해야 하는데 그렇게 되면 너무 로직이 복잡해져서 등록할 때는 multiple로 3개까지 등록을 허용하되, 수정할 때는 한 개씩 등록하도록 하였습니다. 그래서 파일을 첨부하고 확인을 눌렀을 때 등록되는 게 아니라 첨부파일이 변화를 감지했을 때, 즉 파일을 선택한 순간 바로 첨부되는 구조로 하였습니다. 그리고 게시글 작성할 때나 수정할 때 사용하기에 Board Class로 빼서 공용으로 사용하였습니다.
다음 시간에는 글 수정을 하여 DB에 저장하는 부분을 해보겠습니다.
감사합니다.