게시판 - 글쓰기 다중 파일 첨부 & 갯수 제한

이태현·2025년 9월 2일

Web 개발

목록 보기
36/53
post-thumbnail

다중 파일 첨부

    <input type="file" name="attach" id="id_attach" class="mt-2 form-control" multiple>

속성에 multiple을 추가해 주면 여러 파일을 추가할 수 있습니다.

JS

    const id_attach = document.querySelector("#id_attach")
    // const file = id_attach.files[0]

기존에 있던 file 부분을 주석 처리해 주세요. for 문을 통해서 파일을 받아올 겁니다.

    f.append("subject", id_subject.value) // 게시물 제목
    f.append("content", markupStr) // 게시물 내용
    f.append("bcode", bcode) // 게시판 코드
    f.append("mode", "input") // 모드 : 글 등록
    // f.append("files", file) // 파일 첨부
    for (const file of id_attach.files) {
      f.append("files[]", file)
    }

마찬가지로 기존에 append 파일 부분을 주석 처리해 줍니다. 이후 for 문을 통해서 file에 여러 파일을 담아준 후 files[] 배열에 하나씩 담아줍니다.

Array
(
    [files] => Array
        (
            [name] => Array
                (
                    [0] => lake-7938396_640.jpg
                    [1] => bird-9431014_640.jpg
                    [2] => art-9485478_640.jpg
                )

            [full_path] => Array
                (
                    [0] => lake-7938396_640.jpg
                    [1] => bird-9431014_640.jpg
                    [2] => art-9485478_640.jpg
                )

            [type] => Array
                (
                    [0] => image/jpeg
                    [1] => image/jpeg
                    [2] => image/jpeg
                )

            [tmp_name] => Array
                (
                    [0] => C:\xampp\tmp\php42DE.tmp
                    [1] => C:\xampp\tmp\php42DF.tmp
                    [2] => C:\xampp\tmp\php42E0.tmp
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                    [2] => 0
                )

            [size] => Array
                (
                    [0] => 57685
                    [1] => 27791
                    [2] => 33221
                )

        )

)
print_r($_FILES);
exit;

결괏값이 잘 들어가 있는 걸 볼 수 있습니다. 이제 우리는 사용할 값들만 골라주면 됩니다.
기존에 있던 걸 수정해서 사용하는 거라 Frontend 부분은 크게 바뀐 거 없이 끝이 났습니다.

파일 갯수 제한

방법 - 1

    // 파일 첨부 갯수 제한
    if (id_attach.files.length > 3) {
      alert("파일은 3개까지만 올릴 수 있습니다.")
      id_attach.value = ""
      return false
    }

방법 - 2

  // 파일 첨부 갯수 제한
  id_attach.addEventListener("change", () => {
    if (id_attach.files.length > 3) {
      alert("파일은 3개까지만 올릴 수 있습니다.")
      id_attach.value = ""
      return false
    }
  })

마음에 드시는 거 사용하시면 됩니다.

PHP

다중 파일 저장

기존에 파일 첨부 부분을 수정하였습니다.

  // 파일 첨부  // 다중 파일 첨부 // 파일 갯수 제한
  if (isset($_FILES["files"])) {
    // 파일 갯수 제한
    if (sizeof($_FILES["files"]["name"]) > 3) {
      $arr = ["result" => "file_upload_count_exceed"];
      die(json_encode($arr));
    }

    // 다중 파일 첨부
    $tmp_arr = [];
    foreach ($_FILES["files"]["name"] as $key => $val) {
      $full_str = "";
      $tmparr = explode(".", $_FILES["files"]["name"][$key]);
      $ext = end($tmparr);
      $flag = rand(1000, 9999);
      $filename = 'a' . date('YmdHis') . $flag . '.' . $ext;
      $file_ori = $_FILES["files"]["name"][$key]; // 원본 이미지
      copy($_FILES["files"]["tmp_name"][$key], BOARD_DIR . '/' . $filename); // 이미지 파일 저장
      $full_str = $filename . '|' . $file_ori; // 원본 이미지 이름과 바뀐 이미지 이름
      $tmp_arr[] = $full_str;
    }
    $file_list_str = implode("?", $tmp_arr);
  }

파일을 여러 개 저장하면 기존에 저장 방식에서 한 번 더 구분자를 사용해서 만들어주면 됩니다. 필자는 "?"를 사용하여 구분하였습니다.

  • ex) 바꾼 파일 이름 1 | 기존 파일 이름 1? 바꾼 파일 이름 2 | 기존 파일 지름 2

필드를 하나만 사용하기 때문에 이런 식으로 "?"를 기준으로 나눠줄 겁니다.

	print_r($file_list_str);
	exit;

이미지 파일들이 "?"를 기준으로 잘 구분돼서 나온 걸 볼 수 있습니다.

DB & 게시판 폴더 저장 확인

아래와 같이 저장해 보겠습니다.

DB에 해당 데이터가 저장되었습니다.

게시판 이미지 폴더에도 잘 저장되었습니다.

파일 갯수 제한

JS를 우회해서 들어오는 경우도 있기 때문에 항상 Backend 부분에서도 처리를 해주는 게 혹시 모를 예방 차원에서 좋습니다.

  // 파일 첨부  // 다중 파일 첨부 // 파일 갯수 제한
  if (isset($_FILES["files"])) {
    // 파일 갯수 제한
    if (sizeof($_FILES["files"]["name"]) > 3) {
      $arr = ["result" => "file_upload_count_exceed"];
      die(json_encode($arr));
    }

    // 다중 파일 첨부
    $tmp_arr = [];
    foreach ($_FILES["files"]["name"] as $key => $val) {
      $full_str = "";
      $tmparr = explode(".", $_FILES["files"]["name"][$key]);
      $ext = end($tmparr);
      $flag = rand(1000, 9999);
      $filename = 'a' . date('YmdHis') . $flag . '.' . $ext;
      $file_ori = $_FILES["files"]["name"][$key]; // 원본 이미지
      copy($_FILES["files"]["tmp_name"][$key], BOARD_DIR . '/' . $filename); // 이미지 파일 저장
      $full_str = $filename . '|' . $file_ori; // 원본 이미지 이름과 바뀐 이미지 이름
      $tmp_arr[] = $full_str;
    }
    $file_list_str = implode("?", $tmp_arr);
  }

길이를 구하는 방식은 JS에서는 length를 사용하지만 PHP에서는 sizeof나 count를 사용합니다.
이후 Json 형식으로 JS에 응답을 보내주면 해당 결과를 가지고 다음과 같이 제한을 합니다.

마무리

다음 시간에는 파일 용량을 제한하기를 해보겠습니다.

감사합니다.

profile
이해하고 분석하고 지배한다

0개의 댓글