본문 바로가기

비개발자의 개발 일지

현장 팀장에서 수출 ERP까지 — AI와 함께 시스템을 만든 기록

시리즈 보기
php

PHP mkdir() — 폴더(디렉토리) 생성 · is_dir 체크 · 재귀 생성 완전 정리

by 왕진 2026. 7. 11.
반응형

 

 

Web Development · PHP 파일 시스템 함수

PHP mkdir() — 디렉토리(폴더)를 생성하는 함수

퍼미션 0755 · is_dir 체크 · recursive 중첩 생성 완전 정리
시작 오늘 분석할 코드

mkdir()는 지정한 경로에 디렉토리를 생성하는 함수입니다. 두 번째 인수로 퍼미션(기본 0777)을, 세 번째 인수로 중첩 경로를 한 번에 생성할지(recursive) 지정합니다. 이미 존재하는 디렉토리에 mkdir을 호출하면 경고가 발생하므로, 보통 is_dir()로 먼저 확인합니다.

<?php $dirname = "testdir"; if (!is_dir($dirname)) { // 폴더가 없을 때만 생성 mkdir($dirname); print $dirname . " 폴더가 생성됩니다."; } else { print $dirname . " 폴더가 이미 있습니다."; } ?>
실제 출력 미리보기
testdir 없는 경우
testdir 폴더가 생성됩니다.
testdir 이미 있는 경우
testdir 폴더가 이미 있습니다.
용어 용어 정리
mkdir($path)지정 경로에 디렉토리 생성. 성공 true / 실패 false 반환
퍼미션두 번째 인수. 8진수(0755, 0777 등). umask에 의해 실제값이 달라짐
recursive세 번째 인수 true — 중간 경로(부모 폴더)도 없으면 함께 생성
is_dir()경로가 디렉토리인지 확인. 있으면 true — mkdir 전 중복 방지에 사용
umaskUnix 사용 권한 마스크. mkdir 0777 + umask 022 = 실제 755
0755소유자 rwx(7), 그룹 r-x(5), 기타 r-x(5). 웹 서버 표준 디렉토리 권한
rmdir()빈 디렉토리 삭제 함수 — mkdir의 반대 작업
is_writable()디렉토리에 쓰기 권한이 있는지 확인 — 파일 생성 전 체크에 사용

1 퍼미션 인수 — 0755와 0777의 차이
웹 서버 환경에서는 0755가 일반적

두 번째 인수는 디렉토리 생성 퍼미션을 8진수로 지정합니다. 단, Unix 시스템의 umask가 적용되어 실제 퍼미션은 달라집니다. 웹 서버 환경에서는 0755(소유자만 쓰기, 나머지 읽기+실행)가 일반적입니다.

// 퍼미션 명시 지정 mkdir("uploads", 0755); // 소유자: rwx / 그룹·기타: r-x mkdir("private", 0700); // 소유자만 접근 가능 // umask 예시: 기본 umask 022라면 // mkdir($path, 0777) → 실제 0755 (0777 & ~022 = 0755)

2 recursive — 중첩 경로 한 번에 생성
세 번째 인수 true — 부모 폴더까지 함께 만듦

기본적으로 mkdir()은 바로 상위 디렉토리가 있어야 성공합니다. "uploads/2026/06" 처럼 중간 경로가 없으면 실패합니다. 세 번째 인수를 true로 하면 없는 경로를 모두 생성합니다.

// 기본 — 부모 없으면 실패 mkdir("uploads/2026/06"); // uploads가 없으면 실패! // recursive true — 중간 경로 없어도 생성 mkdir("uploads/2026/06", 0755, true); // uploads/ → uploads/2026/ → uploads/2026/06/ 순서로 생성

3 날짜별 업로드 디렉토리 생성 패턴
파일 업로드 처리 전 날짜 폴더 준비
date_default_timezone_set('Asia/Seoul'); // 오늘 날짜 기반 업로드 경로 $upload_dir = "uploads/" . date('Y/m/d'); // → "uploads/2026/06/24" if (!is_dir($upload_dir)) { mkdir($upload_dir, 0755, true); } // 이후 파일 이동 move_uploaded_file( $_FILES['file']['tmp_name'], $upload_dir . '/' . $_FILES['file']['name'] );
※ 다중 요청 환경에서는 두 요청이 동시에 is_dir → mkdir을 실행하면 경쟁 조건이 발생할 수 있습니다. mkdir 반환값을 검사하거나 @mkdir 억제 패턴을 고려하세요.

 

반응형

 

4 경쟁 조건 — @mkdir 억제 패턴
is_dir 확인과 mkdir 사이 타이밍 문제 방지
// @ 연산자로 E_WARNING 억제 후 반환값으로 판단 if (!is_dir($dir) && !@mkdir($dir, 0755, true) && !is_dir($dir)) { // 생성 실패이면서 이미 있지도 않은 경우만 오류 throw new \RuntimeException("디렉토리 생성 실패: {$dir}"); } // is_dir → mkdir 실패 → 다시 is_dir 확인 (이미 생성됐을 수도 있으므로)

5 웹 루트 밖 디렉토리 보안 생성
업로드 파일을 웹에서 직접 접근 불가한 경로에 저장
// document root 밖에 임시 처리 폴더 생성 (더 안전) $safe_dir = dirname($_SERVER['DOCUMENT_ROOT']) . '/private_uploads'; if (!is_dir($safe_dir)) { mkdir($safe_dir, 0750); } // 이 경로는 웹 브라우저에서 URL로 접근 불가 → 보안 파일 저장에 적합

6 자주 하는 실수
실수 증상 해결
is_dir 체크 없이 mkdir 호출 이미 있으면 Warning: mkdir(): File exists if (!is_dir($path)) { mkdir($path, ...); }
중첩 경로에 recursive 없이 사용 부모 디렉토리 없으면 실패 세 번째 인수 true 추가
퍼미션 숫자를 문자열로 전달 mkdir($p, "0755") — 잘못된 권한 8진수 리터럴: 0755 (따옴표 없이)
웹 루트 안에 쓰기 가능 디렉토리 생성 업로드 파일을 URL로 직접 실행 가능 웹 루트 밖 경로 사용 또는 .htaccess 차단
권한 없는 경로에 mkdir Permission denied — 웹 서버 사용자 권한 부족 상위 디렉토리 권한 확인, chown/chmod 조정

핵심 한 줄 요약

mkdir($path, $mode, $recursive)디렉토리 생성 — 성공 true / 실패 false
is_dir 패턴if (!is_dir($d)) { mkdir($d, 0755); } — 중복 생성 방지
recursive세 번째 인수 true — 중첩 경로 한 번에 생성 (기본은 부모 있어야 성공)
퍼미션0755 표준 — 8진수 리터럴로 전달 (문자열 "0755" 안 됨)
보안웹 루트 안 쓰기 가능 폴더 → 업로드 파일 URL 직접 실행 위험

Tags

#PHP #mkdir #폴더생성 #디렉토리생성 #is_dir #recursive #퍼미션 #PHP파일함수 #PHP함수 #PHP학습 #웹개발 #티스토리
▼ 티스토리 태그 입력란 복사용
PHP, mkdir, 폴더생성, 디렉토리생성, is_dir, recursive, 퍼미션, PHP파일함수, PHP함수, PHP학습, 웹개발, 티스토리
반응형

댓글