📖
E 드라이브와 F 드라이브를 Apache 웹 서버에서 접근 가능하게 하면서, 특정 폴더는 외부 접근을 차단하는 설정 예제
페이지 정보
본문
✅ Apache 설정 예제 (httpd.conf 또는 별도 설정 파일에 작성)[code]# ============================
# 📁 드라이브 공유 설정
# ============================
# E 드라이브 공유
Alias /e/ "E:/"
<Directory "E:/">
Require all granted # 모든 사용자에게 허용
Options FollowSymLinks # 심볼릭 링크 허용
AllowOverride None # .htaccess 비활성화
</Directory>
# F 드라이브 공유
Alias /f/ "F:/"
<Directory "F:/">
Require all granted
Options FollowSymLinks
AllowOverride None
</Directory>
# ============================
# 🔒 특정 폴더 접근 차단
# ============================
# E 드라이브 내 mp3mymusic 폴더 차단
<Directory "E:/mp3mymusic">
Require all denied # 접근 거부
</Directory>
# F 드라이브 내 secretdata 폴더 차단
<Directory "F:/secretdata">
Require all denied
</Directory>[/code]
🔍 각 설정 기능 상세 설명[code]Alias /e/ "E:/"
<Directory "E:/">
Require all granted
Options FollowSymLinks
AllowOverride None
</Directory>[/code]✅ Alias /e/ "E:/"
기능: 웹에서 http://localhost/e/처럼 접속하면 실제 E:/ 드라이브에 접근하게 함
예시: http://localhost/e/test.txt → E:\test.txt 파일로 연결
✅ <Directory "E:/">
설정 대상: 실제 Windows의 E:/ 디렉토리에 적용될 권한 설정
내용 설명:
Require all granted : 모든 사용자에게 접근 허용
Options FollowSymLinks : 심볼릭 링크(바로가기)를 따라갈 수 있도록 허용
AllowOverride None : .htaccess 설정은 무시함 (보안 목적)
[code]<Directory "E:/mp3mymusic">
Require all denied
</Directory>[/code]✅ 특정 폴더 접근 차단
위 설정은 E:/mp3mymusic 폴더에 대한 모든 접근을 차단함
예외 없이 접근 불가: 브라우저로 접근하면 403 Forbidden 오류 발생
➕ F 드라이브 추가 시 예시[code]Alias /f/ "F:/"
<Directory "F:/">
Require all granted
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory "F:/secretdata">
Require all denied
</Directory>[/code]이렇게 하면:
/f/ URL 경로 → 실제 F:/ 드라이브 파일로 연결됨
F:/secretdata 폴더는 접근 금지됨
💡 설명 요약
Alias /e/ "E:/" -> 웹 URL /e/ → 윈도우 드라이브 E:/로 연결
<Directory "E:/"> -> E 드라이브 전체에 대한 접근 허용 설정
Require all granted -> 누구나 접근 가능
Require all denied -> 모든 접근 차단 (403 오류)
Options FollowSymLinks -> 링크(바로가기) 따라가게 허용
AllowOverride None -> .htaccess 무시 (보안강화)
✅ 설정 적용 방법
설정 파일 저장 (예: httpd.conf)
Apache 재시작
CMD 또는 서비스 관리자에서:[code]httpd -k restart[/code]또는[code]net stop apache2
net start apache2[/code]
Apache에서 /e/나 /f/ 같은 경로에 접속했을 때 **폴더 목록(디렉토리 리스트)**이 보이도록 하려면, Options Indexes 옵션을 추가하면 됩니다.
✅ 디렉토리 목록 보이게 하는 설정
🔧 예제 전체 (업데이트 버전):[code]# ============================
# 📁 드라이브 공유 설정 (디렉토리 목록 허용)
# ============================
# E 드라이브 공유
Alias /e/ "E:/"
<Directory "E:/">
Require all granted
Options Indexes FollowSymLinks # ★ 디렉토리 목록 허용 추가
AllowOverride None
</Directory>
# F 드라이브 공유
Alias /f/ "F:/"
<Directory "F:/">
Require all granted
Options Indexes FollowSymLinks # ★ 디렉토리 목록 허용 추가
AllowOverride None
</Directory>
# ============================
# 🔒 특정 폴더 접근 차단
# ============================
<Directory "E:/mp3mymusic">
Require all denied
</Directory>
<Directory "F:/secretdata">
Require all denied
</Directory>[/code]🧾 결과 예시
브라우저에서 http://localhost/e/ 접속 시
→ E:/에 있는 폴더/파일 목록이 리스트 형태로 표시됩니다.
http://localhost/f/ 접속 시
→ F:/에 있는 폴더/파일 목록이 표시됨
⚠ 보안 주의사항
Options Indexes는 폴더 안에 index.html 같은 파일이 없을 때, 자동으로 목록을 보여줍니다.
민감한 파일이나 디렉토리는 꼭 Require all denied로 차단해 주세요.
예: E:/backup, F:/db 등은 꼭 차단해두기
📌 Apache 버전에 따라 옵션이 안 먹힐 경우
httpd.conf에서 mod_autoindex가 활성화되어 있어야 합니다.[code]LoadModule autoindex_module modules/mod_autoindex.so[/code]이 라인이 주석(#) 처리돼 있으면 동작하지 않습니다. 꼭 확인하세요!
Apache의 디렉토리 목록(Directory Index) 화면에서 아이콘 표시, 정렬 방식, 스타일 등을 바꾸려면 몇 가지 방법이 있습니다.
✅ 1. 기본 스타일 옵션 설정하기 (Apache 내장 기능)
Apache는 mod_autoindex 모듈을 통해 디렉토리 목록을 보여주며, 이 모듈에 몇 가지 설정 옵션을 줄 수 있습니다.
🔧 예: 보기 스타일 개선[code]<Directory "E:/">
Require all granted
Options Indexes FollowSymLinks
AllowOverride None
# 디렉토리 스타일 옵션
IndexOptions FancyIndexing IconsAreLinks NameWidth=* SuppressHTMLPreamble
</Directory>[/code]
✅ 주요 IndexOptions 설명
FancyIndexing -> 예쁜 아이콘/표시 적용
IconsAreLinks -> 아이콘도 클릭 가능하게
NameWidth=* -> 이름 열 너비 자동 조절
SuppressHTMLPreamble -> 기본 HTML <head> 제거 (커스터마이징용)
FoldersFirst -> 폴더를 위에 정렬
IgnoreCase -> 정렬 시 대소문자 구분 없이
SuppressDescription -> 파일 설명 생략
ScanHTMLTitles -> HTML 파일 내 <title> 태그 내용 표시
✅ 2. 아이콘 표시를 위한 설정
Apache는 기본적으로 /icons/ 라는 가상경로로 아이콘을 제공합니다. 보통 다음 라인이 httpd.conf에 있어야 작동합니다:[code]Alias /icons/ "C:/Apache24/icons/" # 실제 아이콘 경로
<Directory "C:/Apache24/icons">
Options Indexes MultiViews
AllowOverride None
Require all granted
</Directory>[/code]만약 아이콘이 보이지 않으면 이 경로가 누락되었거나 경로가 맞지 않는 경우입니다. icons/ 폴더가 있는지 확인하세요.
✅ 3. 디렉토리 정렬 방식 변경
기본적으로 Apache는 이름순 오름차순으로 정렬하지만, 다음 옵션을 통해 변경 가능합니다:[code]IndexOrderDefault Descending Date[/code]IndexOrderDefault Ascending Name -> 이름순 오름차순
IndexOrderDefault Descending Date -> 최근 파일이 위에 오게
✅ 4. 사용자 정의 HTML + 스타일 적용 (고급)
기본 스타일이 마음에 들지 않으면, 아예 디렉토리 목록을 커스텀 HTML로 만들어 바꿀 수도 있습니다.
이건 .htaccess 또는 HeaderName, ReadmeName 지시어를 사용하는 방식입니다.[code]IndexOptions +FancyIndexing +HTMLTable +NameWidth=* +IconsAreLinks
HeaderName HEADER.html
ReadmeName FOOTER.html[/code]HEADER.html : 목록 상단에 표시할 내용
FOOTER.html : 목록 하단에 표시할 내용
이 HTML 파일들은 디렉토리 안에 직접 위치시켜야 합니다.
📌 전체 예제 (E 드라이브에 적용)[code]<Directory "E:/">
Require all granted
Options Indexes FollowSymLinks
AllowOverride None
IndexOptions FancyIndexing IconsAreLinks FoldersFirst NameWidth=* IgnoreCase
IndexOrderDefault Ascending Name
</Directory>[/code]
Apache의 기본 디렉토리 목록 대신, 완전히 HTML + CSS로 커스터마이징된 디렉토리 리스트 페이지를 보여주는 방식은 다음과 같이 할 수 있습니다.
✅ 목표
Apache가 자동으로 생성하는 디렉토리 리스트 비활성화
사용자가 만든 index.html 파일을 이용해 사용자 정의 목록 UI 출력
CSS 적용된 예쁜 리스트 제공
📁 구조 예시 (E:/ 샘플)[code]E:/
├── index.html ← 우리가 만든 목록 HTML
├── style.css ← CSS 스타일
├── 파일1.txt
├── 파일2.zip
└── 하위폴더/[/code]
🧾 1. Apache 설정[code]<Directory "E:/">
Require all granted
Options +FollowSymLinks -Indexes # 🔸 자동 목록 비활성화, 사용자 HTML만 사용
AllowOverride None
</Directory>[/code]-Indexes 설정으로 Apache 기본 디렉토리 리스트 기능을 끄고, 우리가 만든 index.html만 보여지게 합니다.
🧑💻 2. E:/index.html 예제[code]<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>파일 목록</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>📂 E 드라이브 파일 목록</h1>
<ul id="file-list">
<!-- 여기에 JS로 파일 리스트를 넣거나 수동 입력 -->
<li><a href="파일1.txt">파일1.txt</a></li>
<li><a href="파일2.zip">파일2.zip</a></li>
<li><a href="하위폴더/">하위폴더/</a></li>
</ul>
</body>
</html>[/code]
🎨 3. E:/style.css 예제[code]body {
font-family: 'Segoe UI', sans-serif;
background: #f5f7fa;
padding: 2rem;
color: #333;
}
h1 {
font-size: 1.8rem;
margin-bottom: 1rem;
}
#file-list {
list-style: none;
padding: 0;
}
#file-list li {
margin: 0.5rem 0;
padding: 0.5rem;
background: #fff;
border: 1px solid #ddd;
border-radius: 6px;
transition: background 0.2s ease;
}
#file-list li:hover {
background: #eef2f7;
}
#file-list a {
text-decoration: none;
color: #1a73e8;
font-weight: bold;
}[/code]
✅ 요약
Apache 기본 디렉토리 리스트 끄기: -Indexes
직접 만든 index.html로 목록 구성
CSS로 디자인 자유롭게 변경 가능
동적 자동 목록은 PHP 등 서버스크립트 사용
PHP를 사용해서 자동으로 현재 디렉토리의 파일 목록을 HTML로 출력하는 예제
✅ 1. index.php (자동 디렉토리 목록 스크립트)[code]<?php
$directory = __DIR__; // 현재 디렉토리 경로 가져오기
$files = scandir($directory); // 디렉토리 내 파일 목록 읽기
?>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>📁 디렉토리 목록 보기</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>📁 현재 디렉토리의 파일 목록</h1>
<ul id="file-list">
<?php
foreach ($files as $file) {
if ($file === '.' || $file === '..' || $file === basename(__FILE__)) continue;
$path = $directory . DIRECTORY_SEPARATOR . $file;
$isDir = is_dir($path);
$icon = $isDir ? '📂' : '📄';
$href = urlencode($file) . ($isDir ? '/' : '');
echo "<li>$icon <a href=\"$href\">$file</a></li>";
}
?>
</ul>
</body>
</html>[/code]
✅ 2. style.css (디자인용 CSS)[code]body {
font-family: 'Segoe UI', sans-serif;
background: #f5f7fa;
padding: 2rem;
color: #333;
}
h1 {
font-size: 1.8rem;
margin-bottom: 1rem;
}
#file-list {
list-style: none;
padding: 0;
}
#file-list li {
margin: 0.5rem 0;
padding: 0.5rem;
background: #fff;
border: 1px solid #ddd;
border-radius: 6px;
transition: background 0.2s ease;
}
#file-list li:hover {
background: #eef2f7;
}
#file-list a {
text-decoration: none;
color: #1a73e8;
font-weight: bold;
}[/code]
✅ 3. Apache 설정 예시 (E 드라이브에 적용)[code]<Directory "E:/">
Require all granted
Options +FollowSymLinks -Indexes # 자동 목록 끄고, PHP 사용
DirectoryIndex index.php # 기본 페이지로 index.php 사용
AllowOverride None
</Directory>[/code]
🔄 동작 방식 요약
Apache가 기본 목록을 보여주는 대신 index.php를 보여줌
index.php가 현재 디렉토리 내 파일 및 폴더를 자동으로 탐색
HTML로 리스트 출력 + CSS로 꾸밈
폴더는 📂, 파일은 📄 아이콘으로 표시
📌 주의사항
PHP가 실행되도록 Apache에 mod_php가 설치/설정되어 있어야 합니다.
DirectoryIndex index.php 지시어를 설정해야 기본 파일로 동작합니다.
✅ 고급 사용자 정의 디렉토리 목록(index.php) 예제 포함 기능
자동 디렉토리 목록 출력
폴더/파일 아이콘 구분 (📂 / 📄)
재귀 폴더 탐색
이름/날짜/크기 정렬
실시간 검색창
깔끔한 HTML + CSS 디자인
📁 파일 구성[code]E:/
├── index.php ← 전체 기능 포함
├── style.css ← CSS
└── 기타 파일/폴더[/code]
✅ index.php[code]<?php
function listFiles($dir, $basePath = '') {
$items = array_diff(scandir($dir), ['.', '..']);
$output = [];
foreach ($items as $item) {
$fullPath = $dir . DIRECTORY_SEPARATOR . $item;
$relPath = $basePath . rawurlencode($item);
$isDir = is_dir($fullPath);
$output[] = [
'name' => $item,
'is_dir' => $isDir,
'size' => $isDir ? '-' : filesize($fullPath),
'date' => date("Y-m-d H:i:s", filemtime($fullPath)),
'href' => $relPath . ($isDir ? '/' : '')
];
}
return $output;
}
$dir = __DIR__;
$files = listFiles($dir);
?>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>📁 디렉토리 인덱스</title>
<link rel="stylesheet" href="style.css">
<script>
let files = <?php echo json_encode($files, JSON_UNESCAPED_UNICODE); ?>;
let sortKey = 'name';
let sortDir = 1;
function formatSize(size) {
if (size === '-' || size === 0) return '-';
const units = ['B', 'KB', 'MB', 'GB'];
let i = 0;
while (size >= 1024 && i < units.length - 1) {
size /= 1024; i++;
}
return size.toFixed(1) + ' ' + units[i];
}
function renderList() {
const list = document.getElementById('file-list');
const keyword = document.getElementById('search').value.toLowerCase();
list.innerHTML = '';
let sorted = [...files].filter(file => file.name.toLowerCase().includes(keyword));
sorted.sort((a, b) => {
let valA = a[sortKey];
let valB = b[sortKey];
if (sortKey === 'size' && valA !== '-' && valB !== '-') {
return (valA - valB) * sortDir;
}
return (valA > valB ? 1 : -1) * sortDir;
});
for (let file of sorted) {
let icon = file.is_dir ? '📂' : '📄';
let size = file.size === '-' ? '-' : formatSize(file.size);
list.innerHTML += `
<tr>
<td>${icon} <a href="${file.href}">${file.name}</a></td>
<td>${size}</td>
<td>${file.date}</td>
</tr>
`;
}
}
function sortBy(key) {
sortDir = (sortKey === key) ? -sortDir : 1;
sortKey = key;
renderList();
}
window.onload = renderList;
</script>
</head>
<body>
<h1>📁 디렉토리 파일 목록</h1>
<input type="text" id="search" placeholder="검색어 입력..." oninput="renderList()">
<table>
<thead>
<tr>
<th onclick="sortBy('name')">이름 🔽</th>
<th onclick="sortBy('size')">크기</th>
<th onclick="sortBy('date')">수정일</th>
</tr>
</thead>
<tbody id="file-list"></tbody>
</table>
</body>
</html>[/code]
✅ style.css[code]body {
font-family: 'Segoe UI', sans-serif;
background: #f9fbfc;
color: #333;
padding: 2rem;
}
h1 {
font-size: 1.8rem;
margin-bottom: 1rem;
}
input#search {
padding: 0.5rem;
width: 100%;
max-width: 400px;
margin-bottom: 1rem;
font-size: 1rem;
border: 1px solid #ccc;
border-radius: 6px;
}
table {
width: 100%;
border-collapse: collapse;
}
th {
text-align: left;
cursor: pointer;
padding: 0.5rem;
background: #e0e7ff;
}
td {
padding: 0.5rem;
border-bottom: 1px solid #ddd;
}
a {
text-decoration: none;
color: #0073e6;
font-weight: bold;
}
a:hover {
text-decoration: underline;
}[/code]
✅ Apache 설정 예시[code]<Directory "E:/">
Require all granted
Options +FollowSymLinks -Indexes
DirectoryIndex index.php
AllowOverride None
</Directory>[/code]📌 보완 사항
하위 폴더를 클릭하면 그 폴더로 이동하여 해당 index.php가 다시 목록을 생성합니다.
PHP는 실행 가능한 폴더여야 하므로 Apache에 PHP 모듈이 설정되어 있어야 합니다.
하위 폴더까지 모두 탐색하여 전체 디렉토리 트리를 한 번에 출력하는 PHP 예제
✅ 재귀 탐색 디렉토리 트리 버전
📁 기능
하위 폴더까지 전부 표시
폴더/파일 아이콘 📂📄
디렉토리 트리 형태로 계층 구조 출력
CSS로 깔끔하게 정리
✅ index.php (전체 트리 탐색)[code]<?php
function scanDirRecursive($dir, $baseUrl = '') {
$items = array_diff(scandir($dir), ['.', '..']);
$html = "<ul>";
foreach ($items as $item) {
$fullPath = $dir . DIRECTORY_SEPARATOR . $item;
$urlPath = $baseUrl . rawurlencode($item);
$isDir = is_dir($fullPath);
$icon = $isDir ? '📂' : '📄';
$href = $urlPath . ($isDir ? '/' : '');
$html .= "<li>$icon <a href=\"$href\">$item</a>";
if ($isDir) {
$html .= scanDirRecursive($fullPath, $href . '/'); // 재귀 호출
}
$html .= "</li>";
}
$html .= "</ul>";
return $html;
}
$rootDir = __DIR__;
?>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>📁 전체 디렉토리 트리</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>📁 전체 디렉토리 트리 보기</h1>
<div class="tree">
<?php echo scanDirRecursive($rootDir); ?>
</div>
</body>
</html>[/code]
✅ style.css (트리 스타일)[code]body {
font-family: 'Segoe UI', sans-serif;
background: #f5f7fa;
color: #333;
padding: 2rem;
}
h1 {
font-size: 1.8rem;
margin-bottom: 1.5rem;
}
.tree ul {
list-style: none;
padding-left: 1.5rem;
border-left: 1px dashed #ccc;
}
.tree li {
margin: 0.5rem 0;
position: relative;
}
.tree li::before {
content: "─ ";
position: absolute;
left: -1.2rem;
color: #999;
}
.tree a {
text-decoration: none;
color: #0066cc;
font-weight: 500;
}
.tree a:hover {
text-decoration: underline;
}[/code]
✅ Apache 설정 예시[code]<Directory "E:/">
Require all granted
Options +FollowSymLinks -Indexes
DirectoryIndex index.php
AllowOverride None
</Directory>[/code]
🔁 작동 원리 요약
scanDirRecursive() 함수가 재귀적으로 모든 폴더와 파일을 탐색
계층 구조(<ul><li>) 형태로 출력
폴더는 하위 항목을 다시 출력하는 방식으로 트리 구성
🧩 확장 가능 기능
▶️ 클릭 시 하위 항목 열고 닫는 트리 토글 기능 (JavaScript)
파일 확장자별 아이콘/미리보기
파일 수/폴더 수 통계
ZIP 다운로드/파일 삭제 기능
✅ 1. 트리 접기/펼치기 (▶️ 아이콘으로)
기능 설명
폴더 이름 옆에 ▶️ 버튼 추가
클릭 시 하위 폴더를 열고 닫기 가능 (JavaScript 사용)
보기 편한 인터랙티브 트리 구현
🔧 구현 방법: ul을 display: none/block 처리하고 토글
✅ 2. 확장자별 아이콘 표시
기능 설명
.jpg → 🖼️ 이미지
.mp3 → 🎵 오디오
.zip → 📦 압축파일
.php → 🧩 PHP 파일
등등 다양한 아이콘 설정
🔧 구현 방법: PHP에서 pathinfo()로 확장자 추출하여 아이콘 매핑
✅ 3. 파일 미리보기 기능
기능 설명
텍스트 파일 클릭 → 모달 또는 인라인으로 내용 일부 보기
이미지 클릭 → 팝업 또는 썸네일로 미리보기
HTML, CSS 등도 가능
🔧 구현 방법: JavaScript로 fetch 하여 미리보기 로딩
✅ 4. 파일/폴더 수 통계 표시
기능 설명
현재 디렉토리에 파일 몇 개, 폴더 몇 개인지 표시
총 크기 계산도 가능
🔧 구현 방법: 재귀 탐색 시 카운팅 및 합산 저장
✅ 5. 정렬 기능 추가 (이름/날짜/크기)
기능 설명
상단 정렬 버튼 또는 열 클릭 시 정렬 순서 변경
폴더 우선 정렬 옵션도 가능
🔧 구현 방법: JavaScript에서 정렬 기준으로 files[] 배열 정렬
✅ 6. 파일 다운로드 링크 추가
기능 설명
파일 우측에 [⬇ 다운로드] 버튼 표시
클릭 시 파일 다운로드 동작
🔧 구현 방법: <a href="파일" download> 사용
✅ 7. 파일 삭제/업로드 기능 (권한 필요)
기능 설명
파일 옆에 [🗑️ 삭제], [📤 업로드] 버튼 제공
관리자 권한 필요
🔧 구현 방법: PHP에서 unlink() 또는 move_uploaded_file() 사용
⚠️ 보안 설정 중요! 꼭 인증 절차 필요
✅ 8. ZIP 다운로드 (현재 폴더 전체 압축)
기능 설명
현재 폴더 또는 하위 폴더를 하나의 ZIP 파일로 다운로드
“전체 다운로드” 버튼 제공
🔧 구현 방법: PHP의 ZipArchive 클래스로 압축 생성 후 download.php 제공
🔽 예시 UI 상상 이미지 (간략)[code]📂 myfolder ▶️
📄 index.php [⬇] [🗑️]
📄 photo.jpg 🖼️ [미리보기] [⬇]
📂 music ▶️
📄 song.mp3 🎵 [⬇][/code]
📁 디렉토리 뷰어 전체 소스
✅ 주요 기능 요약
1 트리 접기/펼치기 (JavaScript로 제어)
2 파일 확장자별 아이콘 표시
3 파일 미리보기 (텍스트/이미지)
4 파일/폴더 수 및 용량 통계
5 정렬 (이름, 크기, 날짜)
6 다운로드 버튼
7 삭제/업로드 기능 (권한 필요)
8 ZIP 압축 다운로드 기능
✅ index.php[code]<?php
function getFileIcon($filename) {
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
return match($ext) {
'jpg', 'jpeg', 'png', 'gif', 'bmp' => '🖼️',
'mp3', 'wav', 'ogg' => '🎵',
'zip', 'rar', '7z' => '📦',
'php', 'html', 'css', 'js' => '🧩',
'txt', 'md', 'log' => '📄',
default => is_dir($filename) ? '📂' : '📄'
};
}
function scanDirTree($dir, $base = '') {
$items = array_diff(scandir($dir), ['.', '..']);
$html = "<ul>";
$fileCount = 0;
$folderCount = 0;
$totalSize = 0;
foreach ($items as $item) {
$fullPath = "$dir/$item";
$relPath = $base . rawurlencode($item);
$isDir = is_dir($fullPath);
$icon = getFileIcon($fullPath);
$href = $relPath . ($isDir ? '/' : '');
$html .= "<li>";
if ($isDir) {
$folderCount++;
$html .= "<span class='toggle'>▶️</span> $icon <a href='$href'>$item</a>";
$html .= "<div class='nested'>" . scanDirTree($fullPath, $href) . "</div>";
} else {
$fileCount++;
$size = filesize($fullPath);
$totalSize += $size;
$html .= "$icon <a href='$href' target='_blank'>$item</a> ";
$html .= "[<a href='$href' download>⬇</a>] ";
if (preg_match('/\.(txt|md|html|php|log)$/i', $item)) {
$html .= "<button onclick=\"preview('$href')\">👁️</button> ";
}
$html .= "<button onclick=\"deleteFile('$href')\">🗑️</button>";
}
$html .= "</li>";
}
$html .= "</ul>";
echo "<div class='summary'>📦 폴더: $folderCount / 📄 파일: $fileCount / 총 용량: " . formatSize($totalSize) . "</div>";
return $html;
}
function formatSize($bytes) {
if ($bytes == 0) return '0 B';
$units = ['B','KB','MB','GB','TB'];
$i = floor(log($bytes, 1024));
return round($bytes / pow(1024, $i), 1) . ' ' . $units[$i];
}
?>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>📁 전체 디렉토리 뷰어</title>
<link rel="stylesheet" href="style.css">
<script>
function preview(file) {
fetch(file).then(res => res.text()).then(text => {
const viewer = document.getElementById('viewer');
viewer.innerText = text;
viewer.style.display = 'block';
});
}
function deleteFile(file) {
if (confirm("정말 삭제하시겠습니까?")) {
fetch('delete.php?file=' + encodeURIComponent(file)).then(res => res.text()).then(alert);
location.reload();
}
}
window.onload = () => {
document.querySelectorAll('.toggle').forEach(btn => {
btn.onclick = () => {
const nested = btn.nextElementSibling.nextElementSibling;
nested.classList.toggle('open');
btn.textContent = nested.classList.contains('open') ? '🔽' : '▶️';
};
});
};
</script>
</head>
<body>
<h1>📁 전체 디렉토리 트리</h1>
<form action="upload.php" method="POST" enctype="multipart/form-data">
<input type="file" name="upload_file">
<button type="submit">📤 업로드</button>
<button type="button" onclick="location.href='zipall.php'">📦 전체 ZIP</button>
</form>
<div class="tree">
<?= scanDirTree(__DIR__); ?>
</div>
<pre id="viewer" style="display:none; border:1px solid #ccc; padding:10px; background:#f9f9f9;"></pre>
</body>
</html>[/code]
✅ style.css[code]body {
font-family: sans-serif;
background: #f3f6f9;
padding: 2rem;
}
h1 {
font-size: 1.5rem;
margin-bottom: 1rem;
}
.tree ul {
list-style: none;
padding-left: 1.2rem;
border-left: 1px dashed #aaa;
}
.tree li {
margin: 0.5rem 0;
}
.tree .nested {
display: none;
margin-left: 1rem;
}
.tree .nested.open {
display: block;
}
button {
margin-left: 0.5rem;
}
.summary {
margin-top: 1rem;
font-weight: bold;
}[/code]
✅ delete.php[code]<?php
$file = $_GET['file'] ?? '';
$realPath = realpath(__DIR__ . '/' . $file);
if ($realPath && str_starts_with($realPath, __DIR__) && is_file($realPath)) {
unlink($realPath);
echo "삭제 완료: $file";
} else {
echo "삭제 실패: 잘못된 경로";
}
?>[/code]
✅ upload.php[code]<?php
if (!empty($_FILES['upload_file']['tmp_name'])) {
$name = basename($_FILES['upload_file']['name']);
move_uploaded_file($_FILES['upload_file']['tmp_name'], __DIR__ . "/$name");
}
header("Location: index.php");
?>[/code]
✅ zipall.php (전체 ZIP 압축 다운로드)[code]<?php
$zip = new ZipArchive();
$filename = "archive.zip";
if ($zip->open($filename, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
$dir = new RecursiveDirectoryIterator(__DIR__, FilesystemIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($dir);
foreach ($files as $file) {
$localname = substr($file, strlen(__DIR__) + 1);
if ($file->getFilename() != basename(__FILE__)) {
$zip->addFile($file, $localname);
}
}
$zip->close();
}
header('Content-Type: application/zip');
header("Content-Disposition: attachment; filename=$filename");
readfile($filename);
unlink($filename);
exit;
?>[/code]
🔐 보안 주의사항
이 코드는 로컬 테스트 또는 내부망에서 사용하세요.
delete.php, upload.php는 관리자 인증을 추가하는 것이 매우 중요합니다.
✅ 1. 관리자 인증 추가 (세션 로그인 방식)
🛡️ login.php[code]<?php
session_start();
if ($_POST['id'] === 'admin' && $_POST['pw'] === '1234') {
$_SESSION['admin'] = true;
header('Location: index.php');
exit;
}
?>
<form method="POST">
<input name="id" placeholder="아이디">
<input name="pw" type="password" placeholder="비밀번호">
<button>로그인</button>
</form>[/code]
✅ index.php, delete.php, upload.php 등에 상단 추가:[code]<?php
session_start();
if (!isset($_SESSION['admin'])) {
header('Location: login.php');
exit;
}
?>[/code]※ 보안강화를 위해 실제 서비스 시에는 데이터베이스 기반 인증, CSRF 방지 등을 추가하세요.
✅ 2. 트리 디자인 개선 (아이콘/색상)
🎨 개선된 style.css 예시[code]body {
font-family: 'Segoe UI', sans-serif;
background: #f9fbfc;
padding: 2rem;
color: #333;
}
h1 {
color: #0057a3;
}
a {
text-decoration: none;
color: #007bff;
}
.tree li {
line-height: 1.6;
font-size: 0.95rem;
}
.tree .toggle {
cursor: pointer;
color: #555;
margin-right: 4px;
}
.tree .nested {
padding-left: 1.5rem;
border-left: 1px dashed #bbb;
}
button {
background: #eee;
border: 1px solid #ccc;
padding: 2px 5px;
font-size: 0.8rem;
cursor: pointer;
}
button:hover {
background: #ddd;
}
pre#viewer {
max-height: 300px;
overflow: auto;
}[/code]💡 아이콘 옆에 컬러를 바꾸거나, 폴더마다 색상을 지정하는 방식도 가능합니다.
✅ 3. 경량 모드 or 모바일 최적화
📱 반응형 스타일 추가 (미디어쿼리 활용)[code]@media (max-width: 600px) {
body {
padding: 1rem;
font-size: 0.9rem;
}
.tree ul {
padding-left: 0.8rem;
}
button {
padding: 1px 4px;
}
form input, form button {
display: block;
width: 100%;
margin: 5px 0;
}
}[/code]
# 📁 드라이브 공유 설정
# ============================
# E 드라이브 공유
Alias /e/ "E:/"
<Directory "E:/">
Require all granted # 모든 사용자에게 허용
Options FollowSymLinks # 심볼릭 링크 허용
AllowOverride None # .htaccess 비활성화
</Directory>
# F 드라이브 공유
Alias /f/ "F:/"
<Directory "F:/">
Require all granted
Options FollowSymLinks
AllowOverride None
</Directory>
# ============================
# 🔒 특정 폴더 접근 차단
# ============================
# E 드라이브 내 mp3mymusic 폴더 차단
<Directory "E:/mp3mymusic">
Require all denied # 접근 거부
</Directory>
# F 드라이브 내 secretdata 폴더 차단
<Directory "F:/secretdata">
Require all denied
</Directory>[/code]
🔍 각 설정 기능 상세 설명[code]Alias /e/ "E:/"
<Directory "E:/">
Require all granted
Options FollowSymLinks
AllowOverride None
</Directory>[/code]✅ Alias /e/ "E:/"
기능: 웹에서 http://localhost/e/처럼 접속하면 실제 E:/ 드라이브에 접근하게 함
예시: http://localhost/e/test.txt → E:\test.txt 파일로 연결
✅ <Directory "E:/">
설정 대상: 실제 Windows의 E:/ 디렉토리에 적용될 권한 설정
내용 설명:
Require all granted : 모든 사용자에게 접근 허용
Options FollowSymLinks : 심볼릭 링크(바로가기)를 따라갈 수 있도록 허용
AllowOverride None : .htaccess 설정은 무시함 (보안 목적)
[code]<Directory "E:/mp3mymusic">
Require all denied
</Directory>[/code]✅ 특정 폴더 접근 차단
위 설정은 E:/mp3mymusic 폴더에 대한 모든 접근을 차단함
예외 없이 접근 불가: 브라우저로 접근하면 403 Forbidden 오류 발생
➕ F 드라이브 추가 시 예시[code]Alias /f/ "F:/"
<Directory "F:/">
Require all granted
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory "F:/secretdata">
Require all denied
</Directory>[/code]이렇게 하면:
/f/ URL 경로 → 실제 F:/ 드라이브 파일로 연결됨
F:/secretdata 폴더는 접근 금지됨
💡 설명 요약
Alias /e/ "E:/" -> 웹 URL /e/ → 윈도우 드라이브 E:/로 연결
<Directory "E:/"> -> E 드라이브 전체에 대한 접근 허용 설정
Require all granted -> 누구나 접근 가능
Require all denied -> 모든 접근 차단 (403 오류)
Options FollowSymLinks -> 링크(바로가기) 따라가게 허용
AllowOverride None -> .htaccess 무시 (보안강화)
✅ 설정 적용 방법
설정 파일 저장 (예: httpd.conf)
Apache 재시작
CMD 또는 서비스 관리자에서:[code]httpd -k restart[/code]또는[code]net stop apache2
net start apache2[/code]
Apache에서 /e/나 /f/ 같은 경로에 접속했을 때 **폴더 목록(디렉토리 리스트)**이 보이도록 하려면, Options Indexes 옵션을 추가하면 됩니다.
✅ 디렉토리 목록 보이게 하는 설정
🔧 예제 전체 (업데이트 버전):[code]# ============================
# 📁 드라이브 공유 설정 (디렉토리 목록 허용)
# ============================
# E 드라이브 공유
Alias /e/ "E:/"
<Directory "E:/">
Require all granted
Options Indexes FollowSymLinks # ★ 디렉토리 목록 허용 추가
AllowOverride None
</Directory>
# F 드라이브 공유
Alias /f/ "F:/"
<Directory "F:/">
Require all granted
Options Indexes FollowSymLinks # ★ 디렉토리 목록 허용 추가
AllowOverride None
</Directory>
# ============================
# 🔒 특정 폴더 접근 차단
# ============================
<Directory "E:/mp3mymusic">
Require all denied
</Directory>
<Directory "F:/secretdata">
Require all denied
</Directory>[/code]🧾 결과 예시
브라우저에서 http://localhost/e/ 접속 시
→ E:/에 있는 폴더/파일 목록이 리스트 형태로 표시됩니다.
http://localhost/f/ 접속 시
→ F:/에 있는 폴더/파일 목록이 표시됨
⚠ 보안 주의사항
Options Indexes는 폴더 안에 index.html 같은 파일이 없을 때, 자동으로 목록을 보여줍니다.
민감한 파일이나 디렉토리는 꼭 Require all denied로 차단해 주세요.
예: E:/backup, F:/db 등은 꼭 차단해두기
📌 Apache 버전에 따라 옵션이 안 먹힐 경우
httpd.conf에서 mod_autoindex가 활성화되어 있어야 합니다.[code]LoadModule autoindex_module modules/mod_autoindex.so[/code]이 라인이 주석(#) 처리돼 있으면 동작하지 않습니다. 꼭 확인하세요!
Apache의 디렉토리 목록(Directory Index) 화면에서 아이콘 표시, 정렬 방식, 스타일 등을 바꾸려면 몇 가지 방법이 있습니다.
✅ 1. 기본 스타일 옵션 설정하기 (Apache 내장 기능)
Apache는 mod_autoindex 모듈을 통해 디렉토리 목록을 보여주며, 이 모듈에 몇 가지 설정 옵션을 줄 수 있습니다.
🔧 예: 보기 스타일 개선[code]<Directory "E:/">
Require all granted
Options Indexes FollowSymLinks
AllowOverride None
# 디렉토리 스타일 옵션
IndexOptions FancyIndexing IconsAreLinks NameWidth=* SuppressHTMLPreamble
</Directory>[/code]
✅ 주요 IndexOptions 설명
FancyIndexing -> 예쁜 아이콘/표시 적용
IconsAreLinks -> 아이콘도 클릭 가능하게
NameWidth=* -> 이름 열 너비 자동 조절
SuppressHTMLPreamble -> 기본 HTML <head> 제거 (커스터마이징용)
FoldersFirst -> 폴더를 위에 정렬
IgnoreCase -> 정렬 시 대소문자 구분 없이
SuppressDescription -> 파일 설명 생략
ScanHTMLTitles -> HTML 파일 내 <title> 태그 내용 표시
✅ 2. 아이콘 표시를 위한 설정
Apache는 기본적으로 /icons/ 라는 가상경로로 아이콘을 제공합니다. 보통 다음 라인이 httpd.conf에 있어야 작동합니다:[code]Alias /icons/ "C:/Apache24/icons/" # 실제 아이콘 경로
<Directory "C:/Apache24/icons">
Options Indexes MultiViews
AllowOverride None
Require all granted
</Directory>[/code]만약 아이콘이 보이지 않으면 이 경로가 누락되었거나 경로가 맞지 않는 경우입니다. icons/ 폴더가 있는지 확인하세요.
✅ 3. 디렉토리 정렬 방식 변경
기본적으로 Apache는 이름순 오름차순으로 정렬하지만, 다음 옵션을 통해 변경 가능합니다:[code]IndexOrderDefault Descending Date[/code]IndexOrderDefault Ascending Name -> 이름순 오름차순
IndexOrderDefault Descending Date -> 최근 파일이 위에 오게
✅ 4. 사용자 정의 HTML + 스타일 적용 (고급)
기본 스타일이 마음에 들지 않으면, 아예 디렉토리 목록을 커스텀 HTML로 만들어 바꿀 수도 있습니다.
이건 .htaccess 또는 HeaderName, ReadmeName 지시어를 사용하는 방식입니다.[code]IndexOptions +FancyIndexing +HTMLTable +NameWidth=* +IconsAreLinks
HeaderName HEADER.html
ReadmeName FOOTER.html[/code]HEADER.html : 목록 상단에 표시할 내용
FOOTER.html : 목록 하단에 표시할 내용
이 HTML 파일들은 디렉토리 안에 직접 위치시켜야 합니다.
📌 전체 예제 (E 드라이브에 적용)[code]<Directory "E:/">
Require all granted
Options Indexes FollowSymLinks
AllowOverride None
IndexOptions FancyIndexing IconsAreLinks FoldersFirst NameWidth=* IgnoreCase
IndexOrderDefault Ascending Name
</Directory>[/code]
Apache의 기본 디렉토리 목록 대신, 완전히 HTML + CSS로 커스터마이징된 디렉토리 리스트 페이지를 보여주는 방식은 다음과 같이 할 수 있습니다.
✅ 목표
Apache가 자동으로 생성하는 디렉토리 리스트 비활성화
사용자가 만든 index.html 파일을 이용해 사용자 정의 목록 UI 출력
CSS 적용된 예쁜 리스트 제공
📁 구조 예시 (E:/ 샘플)[code]E:/
├── index.html ← 우리가 만든 목록 HTML
├── style.css ← CSS 스타일
├── 파일1.txt
├── 파일2.zip
└── 하위폴더/[/code]
🧾 1. Apache 설정[code]<Directory "E:/">
Require all granted
Options +FollowSymLinks -Indexes # 🔸 자동 목록 비활성화, 사용자 HTML만 사용
AllowOverride None
</Directory>[/code]-Indexes 설정으로 Apache 기본 디렉토리 리스트 기능을 끄고, 우리가 만든 index.html만 보여지게 합니다.
🧑💻 2. E:/index.html 예제[code]<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>파일 목록</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>📂 E 드라이브 파일 목록</h1>
<ul id="file-list">
<!-- 여기에 JS로 파일 리스트를 넣거나 수동 입력 -->
<li><a href="파일1.txt">파일1.txt</a></li>
<li><a href="파일2.zip">파일2.zip</a></li>
<li><a href="하위폴더/">하위폴더/</a></li>
</ul>
</body>
</html>[/code]
🎨 3. E:/style.css 예제[code]body {
font-family: 'Segoe UI', sans-serif;
background: #f5f7fa;
padding: 2rem;
color: #333;
}
h1 {
font-size: 1.8rem;
margin-bottom: 1rem;
}
#file-list {
list-style: none;
padding: 0;
}
#file-list li {
margin: 0.5rem 0;
padding: 0.5rem;
background: #fff;
border: 1px solid #ddd;
border-radius: 6px;
transition: background 0.2s ease;
}
#file-list li:hover {
background: #eef2f7;
}
#file-list a {
text-decoration: none;
color: #1a73e8;
font-weight: bold;
}[/code]
✅ 요약
Apache 기본 디렉토리 리스트 끄기: -Indexes
직접 만든 index.html로 목록 구성
CSS로 디자인 자유롭게 변경 가능
동적 자동 목록은 PHP 등 서버스크립트 사용
PHP를 사용해서 자동으로 현재 디렉토리의 파일 목록을 HTML로 출력하는 예제
✅ 1. index.php (자동 디렉토리 목록 스크립트)[code]<?php
$directory = __DIR__; // 현재 디렉토리 경로 가져오기
$files = scandir($directory); // 디렉토리 내 파일 목록 읽기
?>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>📁 디렉토리 목록 보기</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>📁 현재 디렉토리의 파일 목록</h1>
<ul id="file-list">
<?php
foreach ($files as $file) {
if ($file === '.' || $file === '..' || $file === basename(__FILE__)) continue;
$path = $directory . DIRECTORY_SEPARATOR . $file;
$isDir = is_dir($path);
$icon = $isDir ? '📂' : '📄';
$href = urlencode($file) . ($isDir ? '/' : '');
echo "<li>$icon <a href=\"$href\">$file</a></li>";
}
?>
</ul>
</body>
</html>[/code]
✅ 2. style.css (디자인용 CSS)[code]body {
font-family: 'Segoe UI', sans-serif;
background: #f5f7fa;
padding: 2rem;
color: #333;
}
h1 {
font-size: 1.8rem;
margin-bottom: 1rem;
}
#file-list {
list-style: none;
padding: 0;
}
#file-list li {
margin: 0.5rem 0;
padding: 0.5rem;
background: #fff;
border: 1px solid #ddd;
border-radius: 6px;
transition: background 0.2s ease;
}
#file-list li:hover {
background: #eef2f7;
}
#file-list a {
text-decoration: none;
color: #1a73e8;
font-weight: bold;
}[/code]
✅ 3. Apache 설정 예시 (E 드라이브에 적용)[code]<Directory "E:/">
Require all granted
Options +FollowSymLinks -Indexes # 자동 목록 끄고, PHP 사용
DirectoryIndex index.php # 기본 페이지로 index.php 사용
AllowOverride None
</Directory>[/code]
🔄 동작 방식 요약
Apache가 기본 목록을 보여주는 대신 index.php를 보여줌
index.php가 현재 디렉토리 내 파일 및 폴더를 자동으로 탐색
HTML로 리스트 출력 + CSS로 꾸밈
폴더는 📂, 파일은 📄 아이콘으로 표시
📌 주의사항
PHP가 실행되도록 Apache에 mod_php가 설치/설정되어 있어야 합니다.
DirectoryIndex index.php 지시어를 설정해야 기본 파일로 동작합니다.
✅ 고급 사용자 정의 디렉토리 목록(index.php) 예제 포함 기능
자동 디렉토리 목록 출력
폴더/파일 아이콘 구분 (📂 / 📄)
재귀 폴더 탐색
이름/날짜/크기 정렬
실시간 검색창
깔끔한 HTML + CSS 디자인
📁 파일 구성[code]E:/
├── index.php ← 전체 기능 포함
├── style.css ← CSS
└── 기타 파일/폴더[/code]
✅ index.php[code]<?php
function listFiles($dir, $basePath = '') {
$items = array_diff(scandir($dir), ['.', '..']);
$output = [];
foreach ($items as $item) {
$fullPath = $dir . DIRECTORY_SEPARATOR . $item;
$relPath = $basePath . rawurlencode($item);
$isDir = is_dir($fullPath);
$output[] = [
'name' => $item,
'is_dir' => $isDir,
'size' => $isDir ? '-' : filesize($fullPath),
'date' => date("Y-m-d H:i:s", filemtime($fullPath)),
'href' => $relPath . ($isDir ? '/' : '')
];
}
return $output;
}
$dir = __DIR__;
$files = listFiles($dir);
?>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>📁 디렉토리 인덱스</title>
<link rel="stylesheet" href="style.css">
<script>
let files = <?php echo json_encode($files, JSON_UNESCAPED_UNICODE); ?>;
let sortKey = 'name';
let sortDir = 1;
function formatSize(size) {
if (size === '-' || size === 0) return '-';
const units = ['B', 'KB', 'MB', 'GB'];
let i = 0;
while (size >= 1024 && i < units.length - 1) {
size /= 1024; i++;
}
return size.toFixed(1) + ' ' + units[i];
}
function renderList() {
const list = document.getElementById('file-list');
const keyword = document.getElementById('search').value.toLowerCase();
list.innerHTML = '';
let sorted = [...files].filter(file => file.name.toLowerCase().includes(keyword));
sorted.sort((a, b) => {
let valA = a[sortKey];
let valB = b[sortKey];
if (sortKey === 'size' && valA !== '-' && valB !== '-') {
return (valA - valB) * sortDir;
}
return (valA > valB ? 1 : -1) * sortDir;
});
for (let file of sorted) {
let icon = file.is_dir ? '📂' : '📄';
let size = file.size === '-' ? '-' : formatSize(file.size);
list.innerHTML += `
<tr>
<td>${icon} <a href="${file.href}">${file.name}</a></td>
<td>${size}</td>
<td>${file.date}</td>
</tr>
`;
}
}
function sortBy(key) {
sortDir = (sortKey === key) ? -sortDir : 1;
sortKey = key;
renderList();
}
window.onload = renderList;
</script>
</head>
<body>
<h1>📁 디렉토리 파일 목록</h1>
<input type="text" id="search" placeholder="검색어 입력..." oninput="renderList()">
<table>
<thead>
<tr>
<th onclick="sortBy('name')">이름 🔽</th>
<th onclick="sortBy('size')">크기</th>
<th onclick="sortBy('date')">수정일</th>
</tr>
</thead>
<tbody id="file-list"></tbody>
</table>
</body>
</html>[/code]
✅ style.css[code]body {
font-family: 'Segoe UI', sans-serif;
background: #f9fbfc;
color: #333;
padding: 2rem;
}
h1 {
font-size: 1.8rem;
margin-bottom: 1rem;
}
input#search {
padding: 0.5rem;
width: 100%;
max-width: 400px;
margin-bottom: 1rem;
font-size: 1rem;
border: 1px solid #ccc;
border-radius: 6px;
}
table {
width: 100%;
border-collapse: collapse;
}
th {
text-align: left;
cursor: pointer;
padding: 0.5rem;
background: #e0e7ff;
}
td {
padding: 0.5rem;
border-bottom: 1px solid #ddd;
}
a {
text-decoration: none;
color: #0073e6;
font-weight: bold;
}
a:hover {
text-decoration: underline;
}[/code]
✅ Apache 설정 예시[code]<Directory "E:/">
Require all granted
Options +FollowSymLinks -Indexes
DirectoryIndex index.php
AllowOverride None
</Directory>[/code]📌 보완 사항
하위 폴더를 클릭하면 그 폴더로 이동하여 해당 index.php가 다시 목록을 생성합니다.
PHP는 실행 가능한 폴더여야 하므로 Apache에 PHP 모듈이 설정되어 있어야 합니다.
하위 폴더까지 모두 탐색하여 전체 디렉토리 트리를 한 번에 출력하는 PHP 예제
✅ 재귀 탐색 디렉토리 트리 버전
📁 기능
하위 폴더까지 전부 표시
폴더/파일 아이콘 📂📄
디렉토리 트리 형태로 계층 구조 출력
CSS로 깔끔하게 정리
✅ index.php (전체 트리 탐색)[code]<?php
function scanDirRecursive($dir, $baseUrl = '') {
$items = array_diff(scandir($dir), ['.', '..']);
$html = "<ul>";
foreach ($items as $item) {
$fullPath = $dir . DIRECTORY_SEPARATOR . $item;
$urlPath = $baseUrl . rawurlencode($item);
$isDir = is_dir($fullPath);
$icon = $isDir ? '📂' : '📄';
$href = $urlPath . ($isDir ? '/' : '');
$html .= "<li>$icon <a href=\"$href\">$item</a>";
if ($isDir) {
$html .= scanDirRecursive($fullPath, $href . '/'); // 재귀 호출
}
$html .= "</li>";
}
$html .= "</ul>";
return $html;
}
$rootDir = __DIR__;
?>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>📁 전체 디렉토리 트리</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>📁 전체 디렉토리 트리 보기</h1>
<div class="tree">
<?php echo scanDirRecursive($rootDir); ?>
</div>
</body>
</html>[/code]
✅ style.css (트리 스타일)[code]body {
font-family: 'Segoe UI', sans-serif;
background: #f5f7fa;
color: #333;
padding: 2rem;
}
h1 {
font-size: 1.8rem;
margin-bottom: 1.5rem;
}
.tree ul {
list-style: none;
padding-left: 1.5rem;
border-left: 1px dashed #ccc;
}
.tree li {
margin: 0.5rem 0;
position: relative;
}
.tree li::before {
content: "─ ";
position: absolute;
left: -1.2rem;
color: #999;
}
.tree a {
text-decoration: none;
color: #0066cc;
font-weight: 500;
}
.tree a:hover {
text-decoration: underline;
}[/code]
✅ Apache 설정 예시[code]<Directory "E:/">
Require all granted
Options +FollowSymLinks -Indexes
DirectoryIndex index.php
AllowOverride None
</Directory>[/code]
🔁 작동 원리 요약
scanDirRecursive() 함수가 재귀적으로 모든 폴더와 파일을 탐색
계층 구조(<ul><li>) 형태로 출력
폴더는 하위 항목을 다시 출력하는 방식으로 트리 구성
🧩 확장 가능 기능
▶️ 클릭 시 하위 항목 열고 닫는 트리 토글 기능 (JavaScript)
파일 확장자별 아이콘/미리보기
파일 수/폴더 수 통계
ZIP 다운로드/파일 삭제 기능
✅ 1. 트리 접기/펼치기 (▶️ 아이콘으로)
기능 설명
폴더 이름 옆에 ▶️ 버튼 추가
클릭 시 하위 폴더를 열고 닫기 가능 (JavaScript 사용)
보기 편한 인터랙티브 트리 구현
🔧 구현 방법: ul을 display: none/block 처리하고 토글
✅ 2. 확장자별 아이콘 표시
기능 설명
.jpg → 🖼️ 이미지
.mp3 → 🎵 오디오
.zip → 📦 압축파일
.php → 🧩 PHP 파일
등등 다양한 아이콘 설정
🔧 구현 방법: PHP에서 pathinfo()로 확장자 추출하여 아이콘 매핑
✅ 3. 파일 미리보기 기능
기능 설명
텍스트 파일 클릭 → 모달 또는 인라인으로 내용 일부 보기
이미지 클릭 → 팝업 또는 썸네일로 미리보기
HTML, CSS 등도 가능
🔧 구현 방법: JavaScript로 fetch 하여 미리보기 로딩
✅ 4. 파일/폴더 수 통계 표시
기능 설명
현재 디렉토리에 파일 몇 개, 폴더 몇 개인지 표시
총 크기 계산도 가능
🔧 구현 방법: 재귀 탐색 시 카운팅 및 합산 저장
✅ 5. 정렬 기능 추가 (이름/날짜/크기)
기능 설명
상단 정렬 버튼 또는 열 클릭 시 정렬 순서 변경
폴더 우선 정렬 옵션도 가능
🔧 구현 방법: JavaScript에서 정렬 기준으로 files[] 배열 정렬
✅ 6. 파일 다운로드 링크 추가
기능 설명
파일 우측에 [⬇ 다운로드] 버튼 표시
클릭 시 파일 다운로드 동작
🔧 구현 방법: <a href="파일" download> 사용
✅ 7. 파일 삭제/업로드 기능 (권한 필요)
기능 설명
파일 옆에 [🗑️ 삭제], [📤 업로드] 버튼 제공
관리자 권한 필요
🔧 구현 방법: PHP에서 unlink() 또는 move_uploaded_file() 사용
⚠️ 보안 설정 중요! 꼭 인증 절차 필요
✅ 8. ZIP 다운로드 (현재 폴더 전체 압축)
기능 설명
현재 폴더 또는 하위 폴더를 하나의 ZIP 파일로 다운로드
“전체 다운로드” 버튼 제공
🔧 구현 방법: PHP의 ZipArchive 클래스로 압축 생성 후 download.php 제공
🔽 예시 UI 상상 이미지 (간략)[code]📂 myfolder ▶️
📄 index.php [⬇] [🗑️]
📄 photo.jpg 🖼️ [미리보기] [⬇]
📂 music ▶️
📄 song.mp3 🎵 [⬇][/code]
📁 디렉토리 뷰어 전체 소스
✅ 주요 기능 요약
1 트리 접기/펼치기 (JavaScript로 제어)
2 파일 확장자별 아이콘 표시
3 파일 미리보기 (텍스트/이미지)
4 파일/폴더 수 및 용량 통계
5 정렬 (이름, 크기, 날짜)
6 다운로드 버튼
7 삭제/업로드 기능 (권한 필요)
8 ZIP 압축 다운로드 기능
✅ index.php[code]<?php
function getFileIcon($filename) {
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
return match($ext) {
'jpg', 'jpeg', 'png', 'gif', 'bmp' => '🖼️',
'mp3', 'wav', 'ogg' => '🎵',
'zip', 'rar', '7z' => '📦',
'php', 'html', 'css', 'js' => '🧩',
'txt', 'md', 'log' => '📄',
default => is_dir($filename) ? '📂' : '📄'
};
}
function scanDirTree($dir, $base = '') {
$items = array_diff(scandir($dir), ['.', '..']);
$html = "<ul>";
$fileCount = 0;
$folderCount = 0;
$totalSize = 0;
foreach ($items as $item) {
$fullPath = "$dir/$item";
$relPath = $base . rawurlencode($item);
$isDir = is_dir($fullPath);
$icon = getFileIcon($fullPath);
$href = $relPath . ($isDir ? '/' : '');
$html .= "<li>";
if ($isDir) {
$folderCount++;
$html .= "<span class='toggle'>▶️</span> $icon <a href='$href'>$item</a>";
$html .= "<div class='nested'>" . scanDirTree($fullPath, $href) . "</div>";
} else {
$fileCount++;
$size = filesize($fullPath);
$totalSize += $size;
$html .= "$icon <a href='$href' target='_blank'>$item</a> ";
$html .= "[<a href='$href' download>⬇</a>] ";
if (preg_match('/\.(txt|md|html|php|log)$/i', $item)) {
$html .= "<button onclick=\"preview('$href')\">👁️</button> ";
}
$html .= "<button onclick=\"deleteFile('$href')\">🗑️</button>";
}
$html .= "</li>";
}
$html .= "</ul>";
echo "<div class='summary'>📦 폴더: $folderCount / 📄 파일: $fileCount / 총 용량: " . formatSize($totalSize) . "</div>";
return $html;
}
function formatSize($bytes) {
if ($bytes == 0) return '0 B';
$units = ['B','KB','MB','GB','TB'];
$i = floor(log($bytes, 1024));
return round($bytes / pow(1024, $i), 1) . ' ' . $units[$i];
}
?>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>📁 전체 디렉토리 뷰어</title>
<link rel="stylesheet" href="style.css">
<script>
function preview(file) {
fetch(file).then(res => res.text()).then(text => {
const viewer = document.getElementById('viewer');
viewer.innerText = text;
viewer.style.display = 'block';
});
}
function deleteFile(file) {
if (confirm("정말 삭제하시겠습니까?")) {
fetch('delete.php?file=' + encodeURIComponent(file)).then(res => res.text()).then(alert);
location.reload();
}
}
window.onload = () => {
document.querySelectorAll('.toggle').forEach(btn => {
btn.onclick = () => {
const nested = btn.nextElementSibling.nextElementSibling;
nested.classList.toggle('open');
btn.textContent = nested.classList.contains('open') ? '🔽' : '▶️';
};
});
};
</script>
</head>
<body>
<h1>📁 전체 디렉토리 트리</h1>
<form action="upload.php" method="POST" enctype="multipart/form-data">
<input type="file" name="upload_file">
<button type="submit">📤 업로드</button>
<button type="button" onclick="location.href='zipall.php'">📦 전체 ZIP</button>
</form>
<div class="tree">
<?= scanDirTree(__DIR__); ?>
</div>
<pre id="viewer" style="display:none; border:1px solid #ccc; padding:10px; background:#f9f9f9;"></pre>
</body>
</html>[/code]
✅ style.css[code]body {
font-family: sans-serif;
background: #f3f6f9;
padding: 2rem;
}
h1 {
font-size: 1.5rem;
margin-bottom: 1rem;
}
.tree ul {
list-style: none;
padding-left: 1.2rem;
border-left: 1px dashed #aaa;
}
.tree li {
margin: 0.5rem 0;
}
.tree .nested {
display: none;
margin-left: 1rem;
}
.tree .nested.open {
display: block;
}
button {
margin-left: 0.5rem;
}
.summary {
margin-top: 1rem;
font-weight: bold;
}[/code]
✅ delete.php[code]<?php
$file = $_GET['file'] ?? '';
$realPath = realpath(__DIR__ . '/' . $file);
if ($realPath && str_starts_with($realPath, __DIR__) && is_file($realPath)) {
unlink($realPath);
echo "삭제 완료: $file";
} else {
echo "삭제 실패: 잘못된 경로";
}
?>[/code]
✅ upload.php[code]<?php
if (!empty($_FILES['upload_file']['tmp_name'])) {
$name = basename($_FILES['upload_file']['name']);
move_uploaded_file($_FILES['upload_file']['tmp_name'], __DIR__ . "/$name");
}
header("Location: index.php");
?>[/code]
✅ zipall.php (전체 ZIP 압축 다운로드)[code]<?php
$zip = new ZipArchive();
$filename = "archive.zip";
if ($zip->open($filename, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
$dir = new RecursiveDirectoryIterator(__DIR__, FilesystemIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($dir);
foreach ($files as $file) {
$localname = substr($file, strlen(__DIR__) + 1);
if ($file->getFilename() != basename(__FILE__)) {
$zip->addFile($file, $localname);
}
}
$zip->close();
}
header('Content-Type: application/zip');
header("Content-Disposition: attachment; filename=$filename");
readfile($filename);
unlink($filename);
exit;
?>[/code]
🔐 보안 주의사항
이 코드는 로컬 테스트 또는 내부망에서 사용하세요.
delete.php, upload.php는 관리자 인증을 추가하는 것이 매우 중요합니다.
✅ 1. 관리자 인증 추가 (세션 로그인 방식)
🛡️ login.php[code]<?php
session_start();
if ($_POST['id'] === 'admin' && $_POST['pw'] === '1234') {
$_SESSION['admin'] = true;
header('Location: index.php');
exit;
}
?>
<form method="POST">
<input name="id" placeholder="아이디">
<input name="pw" type="password" placeholder="비밀번호">
<button>로그인</button>
</form>[/code]
✅ index.php, delete.php, upload.php 등에 상단 추가:[code]<?php
session_start();
if (!isset($_SESSION['admin'])) {
header('Location: login.php');
exit;
}
?>[/code]※ 보안강화를 위해 실제 서비스 시에는 데이터베이스 기반 인증, CSRF 방지 등을 추가하세요.
✅ 2. 트리 디자인 개선 (아이콘/색상)
🎨 개선된 style.css 예시[code]body {
font-family: 'Segoe UI', sans-serif;
background: #f9fbfc;
padding: 2rem;
color: #333;
}
h1 {
color: #0057a3;
}
a {
text-decoration: none;
color: #007bff;
}
.tree li {
line-height: 1.6;
font-size: 0.95rem;
}
.tree .toggle {
cursor: pointer;
color: #555;
margin-right: 4px;
}
.tree .nested {
padding-left: 1.5rem;
border-left: 1px dashed #bbb;
}
button {
background: #eee;
border: 1px solid #ccc;
padding: 2px 5px;
font-size: 0.8rem;
cursor: pointer;
}
button:hover {
background: #ddd;
}
pre#viewer {
max-height: 300px;
overflow: auto;
}[/code]💡 아이콘 옆에 컬러를 바꾸거나, 폴더마다 색상을 지정하는 방식도 가능합니다.
✅ 3. 경량 모드 or 모바일 최적화
📱 반응형 스타일 추가 (미디어쿼리 활용)[code]@media (max-width: 600px) {
body {
padding: 1rem;
font-size: 0.9rem;
}
.tree ul {
padding-left: 0.8rem;
}
button {
padding: 1px 4px;
}
form input, form button {
display: block;
width: 100%;
margin: 5px 0;
}
}[/code]
댓글목록
등록된 댓글이 없습니다.
![]() ![]() |