📖
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]

댓글목록

등록된 댓글이 없습니다.


자료 목록
번호 제목 날짜
173
🫧
04-17
172
🫧
04-17
📖
🫧
04-16
170
🫧
04-15
169
🫧
04-15
168
🫧
04-13
167
🫧
04-13
166
🫧
04-13
165
🫧
04-13
164
🫧
04-13
163
🫧
04-10
162
🫧
04-10
161
🫧
04-09
160
🫧
04-09
159
🫧
04-08

🔍 검색

회사소개 개인정보처리방침 서비스이용약관
Copyright © rainbowgarden.shop All rights reserved.