PHP 파일 다운로드 시 한글 파일명 깨짐 문제 해결하기

프리터코더·2025년 6월 2일

php 문제 해결

목록 보기
55/79

PHP로 파일 다운로드 기능을 구현할 때 한글 파일명이 깨지는 문제는 매우 흔한 이슈입니다. 브라우저마다 다른 인코딩 방식을 사용하기 때문에 발생하는 문제로, 다음과 같은 해결책들을 사용할 수 있습니다.

1. UTF-8 인코딩과 URL 인코딩 사용

<?php
$filename = "한글파일명.pdf";
$filepath = "/path/to/file/" . $filename;

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . urlencode($filename) . '"');
header('Content-Length: ' . filesize($filepath));

readfile($filepath);
?>

2. RFC 2231 표준 사용

<?php
$filename = "한글파일명.pdf";
$filepath = "/path/to/file/" . $filename;

header('Content-Type: application/octet-stream');
header("Content-Disposition: attachment; filename*=UTF-8''" . rawurlencode($filename));
header('Content-Length: ' . filesize($filepath));

readfile($filepath);
?>

3. 브라우저별 분기 처리

<?php
$filename = "한글파일명.pdf";
$filepath = "/path/to/file/" . $filename;

$user_agent = $_SERVER['HTTP_USER_AGENT'];

if (strpos($user_agent, 'MSIE') !== false || strpos($user_agent, 'Trident') !== false) {
    // Internet Explorer
    $encoded_filename = urlencode($filename);
} else {
    // Chrome, Firefox, Safari 등
    $encoded_filename = $filename;
}

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
header('Content-Length: ' . filesize($filepath));

readfile($filepath);
?>

4. 멀티바이트 안전한 처리

<?php
$filename = "한글파일명.pdf";
$filepath = "/path/to/file/" . $filename;

// UTF-8로 인코딩 확인 및 변환
if (!mb_check_encoding($filename, 'UTF-8')) {
    $filename = mb_convert_encoding($filename, 'UTF-8', 'auto');
}

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . rawurlencode($filename) . '"; filename*=UTF-8\'\'' . rawurlencode($filename));
header('Content-Length: ' . filesize($filepath));

readfile($filepath);
?>

5. 완전한 다운로드 함수

<?php
function downloadFile($filepath, $filename = null) {
    if (!file_exists($filepath)) {
        die('파일이 존재하지 않습니다.');
    }
    
    if ($filename === null) {
        $filename = basename($filepath);
    }
    
    // 출력 버퍼 정리
    if (ob_get_level()) {
        ob_end_clean();
    }
    
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . rawurlencode($filename) . '"; filename*=UTF-8\'\'' . rawurlencode($filename));
    header('Content-Length: ' . filesize($filepath));
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    
    readfile($filepath);
    exit;
}

// 사용 예시
downloadFile('/path/to/file.pdf', '한글파일명.pdf');
?>

6. Base64 인코딩 방식

<?php
$filename = "한글파일명.pdf";
$filepath = "/path/to/file/" . $filename;

$encoded_filename = '=?UTF-8?B?' . base64_encode($filename) . '?=';

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
header('Content-Length: ' . filesize($filepath));

readfile($filepath);
?>

핵심 포인트

  • RFC 2231 표준을 사용하는 것이 가장 안전합니다
  • rawurlencode() 함수를 사용하여 URL 인코딩을 적용하세요
  • filename과 filename* 두 속성을 모두 제공하면 브라우저 호환성이 높아집니다
  • 파일 다운로드 전에 출력 버퍼를 정리하는 것이 중요합니다
profile
일용직 개발자. freetercoder@gmail.com

0개의 댓글