PHP에서 다운로드로직을 구현할때 서버부하문제를 고려한 방법
PHP에서 파일을 웹브라우저에 보내는 방법은 readfile()함수를 사용하는것이 일반적입니다. [code]
<?php
$file = 'monkey.gif';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
[/code]
그러나 이경우 readfile()은 RAM 메모리에 저장되기때문에 다운로드요청이 많아지거나 파일용량이 큰 경우 RAM 부하가 발생하는 문제가 있습니다.
이 문제를 다음과 같은 방법으로 해결할수 있습니다.
[code]
function download($path, $buf=64)
{
$fullpath = $path;
$name = pathinfo($fullpath)['basename'];
if(strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) // Browser is Internet Explorer
{
$filename = urlencode($name);
$filename = preg_replace('/\./', '%2e', $filename, substr_count($filename, '.') - 1);
$filename = basename(str_replace("+", "%20", $filename));
}
else $filename = $name;
if (!is_file($fullpath) or connection_status()!=0) return(false);
while(ob_get_level()) @ob_end_clean();
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Pragma: public");
header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Content-Type: application/octet-stream");
header("Content-Length: ".(string)(filesize($fullpath)));
header("Content-Disposition: inline; filename=\"$filename\""); // Important the quotes \"\" for Firefox
header("Content-Transfer-Encoding: binary\n");
if($this->getUseSession() === true) session_write_close();
if ($file = fopen($fullpath, 'rb'))
{
while(!feof($file) and (connection_status()==0))
{
set_time_limit(0); // Need if use max_execution_time set with php.ini.
print(fread($file, 1024*intval($buf)));
@ob_flush();
@flush();
}
fclose($file);
}
return((connection_status()==0) and !connection_aborted());
}
[/code]
위와 같이 하면 메모리영역은 $buf크기만큼만 점유하면서 웹브라우저에 전송되게 됩니다.
물론 속도가 뜬 결함이 있을수 있으나 용량이 큰 파일들을 다운로드 할때에는 위와 같은 방법이 서버부하를 줄이면서도 안전하다고 생각합니다.
게시판 목록
개발자팁
개발과 관련된 유용한 정보를 공유하세요.
질문은 QA에서 해주시기 바랍니다.
질문은 QA에서 해주시기 바랍니다.
| 번호 | 분류 | 제목 | 글쓴이 | 날짜 | 조회 |
|---|---|---|---|---|---|
| 5066 | 기타 |
DogFoot개발
|
4년 전 | 1819 | |
| 5065 | PHP |
DogFoot개발
|
4년 전 | 1529 | |
| 5064 | PHP |
happyl
|
4년 전 | 1918 | |
| 5063 | node.js |
DogFoot개발
|
4년 전 | 1674 | |
| 5062 | node.js |
DogFoot개발
|
4년 전 | 1693 | |
| 5061 | node.js |
DogFoot개발
|
4년 전 | 1416 | |
| 5060 | node.js |
DogFoot개발
|
4년 전 | 1254 | |
| 5059 | node.js |
DogFoot개발
|
4년 전 | 1250 | |
| 5058 | 기타 |
DogFoot개발
|
4년 전 | 2697 | |
| 5057 | 웹서버 |
DogFoot개발
|
4년 전 | 2726 | |
| 5056 | MySQL | 4년 전 | 1506 | ||
| 5055 | 기타 | 4년 전 | 1435 | ||
| 5054 | OS | 4년 전 | 2070 | ||
| 5053 | 웹서버 | 4년 전 | 3632 | ||
| 5052 | OS | 4년 전 | 2424 | ||
| 5051 | PHP | 4년 전 | 2189 | ||
| 5050 | 웹서버 | 4년 전 | 1720 | ||
| 5049 | MySQL | 4년 전 | 1899 | ||
| 5048 | OS | 4년 전 | 2704 | ||
| 5047 | PHP | 4년 전 | 4375 | ||
| 5046 | MySQL | 4년 전 | 1820 | ||
| 5045 | MySQL | 4년 전 | 1944 | ||
| 5044 | MySQL | 4년 전 | 4135 | ||
| 5043 | MySQL | 4년 전 | 1891 | ||
| 5042 | 기타 |
|
4년 전 | 2636 | |
| 5041 | MySQL | 4년 전 | 1998 | ||
| 5040 | MySQL | 4년 전 | 1726 | ||
| 5039 | MySQL | 4년 전 | 1499 | ||
| 5038 | MySQL | 4년 전 | 1336 | ||
| 5037 | OS | 4년 전 | 4432 |
댓글 작성
댓글을 작성하시려면 로그인이 필요합니다.
로그인하기