반응형
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학습, 웹개발, 티스토리
반응형
'php' 카테고리의 다른 글
| PHP pathinfo() — 경로 정보 분해 · dirname · basename · extension 완전 정리 (0) | 2026.07.11 |
|---|---|
| PHP rmdir() — 빈 폴더 삭제 · is_dir 체크 · 재귀 삭제 완전 정리 (0) | 2026.07.11 |
| PHP unlink() — 파일 삭제 · is_file 체크 · 임시파일 처리 완전 정리 (0) | 2026.07.11 |
| PHP copy() — 파일 복사 · 백업 패턴 · rename과 차이 완전 정리 (0) | 2026.07.11 |
| PHP file_put_contents() — 파일 쓰기 · FILE_APPEND · LOCK_EX 완전 정리 (0) | 2026.07.11 |
왕진 블로그

댓글