<a href="파일명">다운로드</a>
처음에는 이렇게 하면 그냥 다운이 되는 줄 알았습니다. 아래에는 제 생각에 대한 결과 값입니다. 파일이 다운로드 되긴 합니다만 이미지 같은 경우에는 제대로 다운로드 되지도 않고 파일 위치가 URL에 그대로 노출되고 엑셀파일 역시 파일명은 member.xls인데 저장되는 파일명은 또 파일 소스가 그대로 노출되어 담겨서 저장되었습니다.




echo "<a href='./data/board/" . $file_source . "'>" . $file_name . "</a><br>";
echo "<a href=\"data/board/$file_source\">$file_name</a>";
두 코드 중에 편하신 거 사용하시면 됩니다.
<?php
$idx = isset($_GET['idx']) && $_GET['idx'] != '' && is_numeric($_GET['idx']) ? $_GET['idx'] : '';
$th = isset($_GET['th']) && $_GET['th'] != '' && is_numeric($_GET['th']) ? $_GET['th'] : '';
if ($idx == '') {
die('
<script>
alert("게시물 번호가 누락되었습니다.")
</script>');
}
if ($th == '') {
die('
<script>
alert("파일의 순서가 누락되었습니다.")
</script>');
}
include '../inc/dbconfig.php';
include '../inc/board.php'; // 게시판 클래스
$board = new Board($db);
$fileinfo = $board->getAttachFile($idx, $th);
list($file_source, $file_name) = explode('|', $fileinfo);
if ($file_source == '' || $file_name == '') {
die('
<script>
alert("파일 정보가 누락되었습니다.")
</script>');
}
$down = BOARD_DIR . '/' . $file_source;
if (!file_exists($down)) {
die('
<script>
alert("존재하지 않는 파일입니다.")
</script>');
}
$filesize = filesize($down);
header("Content-Type:application/octet-stream");
header("Content-Disposition:attachment;filename=$file_name"); // 다운로드 받을 파일이름 지정
header("Content-Transfer-Encoding:binary");
header("Content-Length:" . $filesize);
header("Cache-Control:cache,must-revalidate");
header("Pragma:no-cache");
$fp = fopen($down, 'r');
while (!feof($fp)) {
$buf = fread($fp, 8096);
print($buf);
flush();
}
fclose($fp);
서버에 있는 파일을 다운로드하기 위해서 header() 함수를 사용해야 합니다.
출 처 : https://m.blog.naver.com/imm7745/221782552329
파일 소스나 파일명을 가져오기 위해서 DB를 연결하거나 Get방식으로 변경하겠습니다.
$th = 0;
foreach ($filelist as $file) {
list($file_source, $file_name) = explode('|', $file);
echo "<a href=\"./pg/boarddownload.php?idx=$idx&th=$th\">$file_name</a><br>";
// echo "<a href='./data/board/" . $file_source . "'>" . $file_name . "</a><br>";
$th++;
}
첨부파일을 다운로드하기 위해서 idx 값이 필요합니다. 그런데 파일이 2개 이상이면 어떤 파일이 먼저인지 알 수가 없어서 순서를 정해줘야 합니다. 그러기 위해선 링크에 쿼리 값을 추가를 해줘야 합니다. 그러면 th 값 첫 번째 파일은 0번째 두 번째 파일은 1번째가 됩니다.


// 첨부파일 구하기
public function getAttachFile($idx, $th)
{
$sql = "SELECT files FROM board WHERE idx=:idx";
$stmt = $this->conn->prepare($sql);
$params = [":idx" => $idx];
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute($params);
$row = $stmt->fetch();
$filelist = explode('?', $row['files']);
return $filelist[$th];
}
explode() 함수를 사용하여 '?'를 기준으로 각 배열에 첫 번째 파일과 두 번째 파일이 잘 들어간 걸 볼 수 있습니다. 이제 나눠진 두 개의 파일을 가지고 해당 첨부파일이 어떤 거지 알 수 있게 되었습니다.
$fileinfo = $board->getAttachFile($idx, $th);
위에 코드를 실행하면 idx값과 th값으로 인해 아래와 같이 해당 파일 하나만 출력됩니다.

list($file_source, $file_name) = explode('|', $fileinfo);
첫 번째 파일을 가지고 '|'를 기준으로 다시 한번 더 나눠서 list($file_source, $file_name) 함수에 담긴 $file_source 값과 $file_name에 각각 파일 소스와 파일명을 담아주면 끝입니다.

이렇게 하면 더 이상 파일 소스가 노출되지 않고 파일 원본 이름으로 잘 나오는 걸 볼 수 있습니다.
다음 시간에는 다운로드 횟수 기록을 해보겠습니다.
감사합니다.