본문 바로가기

WordPress/File Upload

WordPress Fileupload & Download example

워드프레스에서 파일업로드/다운로드 예



개요

워드프레스에서 한글 파일명이 업로드되는 경우 발생하는 문제와 다운로드시 한글 파일명이 보이지 않는 문제 등을 테스트하고 해결하는 방법을 알아보고자 한다. 플러그인을 사용하는 것이 아니고 워드프레스 템플릿 페이지에 업로드용 폼을 만들고 폼에서 직접 서버측 php 파일에 폼을 전송하는 방법을 사용하였다. 그러므로 워드프레스의 특성은 거의 포함되지 않고 PHP 에서 업/다운로드를 작성하는 방법을 테스트하려고 한다



테스트 환경

Windows 8

Autoset9

WordPress 4.4

Google Chrome

txt, pdf, png, jpg, hwp, mp4 등의 파일을 업로드하고 다운로드하는데 문제 없음



파일 전송 폼

<form action="../my-file-upload.php" method="post" enctype="multipart/form-data">
    파일선택:
    <input type="file" name="file1" id="file1">
설명 : <input type="text" name="desc" id="desc" value="파일 업로드 테스트">
    <input type="submit" value="Upload File" name="submit">
</form>



wordpress루트 폴더/my-file-upload.php

위의 폼에서 전송한 텍스트와 파일을 서버측에서 수신하는 PHP 코드

<?php
function log_d($tag, $msg) {
	$file = fopen('my-debug.log','a');
	fwrite($file, $tag.':'.$msg."\r\n");
	fclose($file);
}

// 폼의 일반 텍스트 필드에 입력된 값을 받는다
$desc = $_POST['desc'];

$target_dir = "C:/test/uploads/";

if($_FILES["file1"]["error"] > 0 ) {
  log_d('Upload', 'Upload Fail');
}else {

  $tmp_name = basename($_FILES["file1"]["tmp_name"]);
  $name = $_FILES["file1"]["name"]; // 일반 문자열이나 DB에 사용할 파일이름	(UTF-8)
  $filename = iconv("UTF-8", "EUC-KR", $name);// 실제 파일시스템에 사용	(EUC-KR)
  
  log_d('name encoding', mb_detect_encoding($name));
  log_d('filename encoding', mb_detect_encoding($filename));
	log_d('tmp_name', $tmp_name);
	log_d('name', $name);
	log_d('filename', $filename);
	if(!empty($_FILES["file1"]["tmp_name"])) {
		log_d('Upload', 'Upload OK');
		$moved = move_uploaded_file($_FILES["file1"]["tmp_name"], $target_dir.$filename);
		if($moved) {
			log_d('moved', $moved);
		}
	}
}

function conn() {
	$host = "localhost";
	$user = "root";
	$pw = "autoset";
	$db = "wordpress";

	// Create connection
	$conn = new mysqli($host, $user, $pw, $db);
	// Check connection
	if ($conn->connect_error) {
		die("Connection failed: " . $conn->connect_error);
	}
	return $conn;
}

function insert($fn, $desc){
	$conn = conn();
	$sql = "INSERT INTO file_info_tb (filename, desc)
	VALUES ('".$fn."', '".$desc."')";

	if ($conn->query($sql) === TRUE) {
		$last_id = $conn->insert_id;
		log_d('레코드 추가', "New record created successfully. Last inserted ID is: " . $last_id);
	} else {
		log_d('추가 오류',  "Error: " . $sql . "\r\n" . $conn->error);
	}

	$conn->close();
}

insert($name, $desc); //DB에는 utf-8형식으로 문자열을 저장
header("Location: http://localhost/download/");
?>



워드프레스 루트폴더/download.php

http 헤더를 이용하여 다운로드 기능을 구현할 때는 PHP 파일을 통해 브라우저에 전달되는 데이터에 파일 데이터 이외의 다른 데이터가 포함되면 파일이 손상된다. 특히 <?php 앞에 어떠한 공백도 있어서는 안된다. 웹브라우저 파라미터가 UTF-8 형식으로 전달되므로 윈도우의 파일 시스템에 사용하는 EUC-KR형식으로 변환해서 파일의 경로로 사용해야 한다. 리눅스의 파일 시스템에는 UTF-8형식이 기본으로 사용된다. MySQL 데이터베이스에 저장된 데이터도 UTF-8 형식으로 읽어오므로 웹브라우저 파라미터와 같은 EUC-KR 형식으로 변환 절차를 거쳐 파일의 경로로 사용해야 한다

<?php

function mb_basename($path) { return end(explode('/',$path)); } 
function utf2euc($str) { return iconv("UTF-8","euc-kr//IGNORE", $str); }// euc-kr 대신 cp949가능
function is_ie() {
	if(!isset($_SERVER['HTTP_USER_AGENT']))return false;
	if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) return true; // IE8
	if(strpos($_SERVER['HTTP_USER_AGENT'], 'Windows NT 6.1') !== false) return true; // IE11
	return false;
}
function log_d($tag, $msg) {
	$file = fopen('my-debug.log','a');
	fwrite($file, $tag.':'.$msg."\r\n");
	fclose($file);
}

$name = $_POST['file_to_download'];	// UTF-8형식의 파라미터 
$name = iconv('UTF-8','EUC-KR', $name); // 파일시스템에 사용되는 형식(EUC-KR)으로 변환

$filepath = 'C:/test/uploads/'.$name;
$filesize = filesize($filepath);
$filename = mb_basename($filepath);

//if( is_ie() ) $filename = utf2euc($filename);

Header("Content-Type: application/octet-stream");
Header("Content-Disposition: attachment; filename=\"$filename\""); 
header("Content-Description: File Transfer");
header("Content-Transfer-Encoding: binary");
Header("Content-Length: ".$filesize);
Header("Pragma: no-cache");
Header("Expires: 0");

if(is_ie()){
	header("Pragma: no-cache; public");
	header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
}

if (is_file("$filepath")) 
{ 	
	readfile($filepath);
	/*
	$fp = fopen("$filepath", "rb"); 
	fpassthru($fp);
	fclose($fp);
	*/
	/*
	$fp = fopen("$filepath", "rb"); 
	while(!feof($fp)){ 
		echo fread($fp,1048576*2);
		flush();
        };
	fclose($fp);
	*/
} 
?>