PHP readfile은 보내기 전에 페이지 버퍼를 사용하여 파일을 저장합니다. 메모리 부족으로 인해 실패하면 메모리 오류가 발생하지 않습니다.
큰 파일은 파일을 읽고 내용을 넣어하는 FREAD fopen을 사용하는 다운로드가 페이지 버퍼 (
http://us1.php.net/manual/es/ref.outcontrol.php)
를 사용하지 않는 수행하는 페이지가 또한 더 있는지 확인합니다. 또한 fread를 사용하면 다운로드를 다시 시작할 수 있도록 몇 가지 코드를 만들 수 있습니다.0, Resumable downloads when using PHP to send the file?
프로세스 (위해서는 ob_end_clean 시작하기 전에 청소를 시도해야 OUPUT 버퍼링과 끝 버퍼를 해제) 또는 ('output_buffering을'을 위해서는 ini_set 사용하여 출력 버퍼링을 비활성화하려면 :
여기 좋은 예가있다); 또한 같은 페이지에서 부분적인 다운로드를 지원하는 예를 들어 거기
http://ca2.php.net/manual/en/function.readfile.php#48683
function readfile_chunked($filename,$retbytes=true) {
$chunksize = 1*(1024*1024); // how many bytes per chunk
$buffer = '';
$cnt =0;
$handle = fopen($filename, 'rb');
if ($handle === false) {
return false;
}
while (!feof($handle)) {
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
if ($retbytes) {
$cnt += strlen($buffer);
}
}
$status = fclose($handle);
if ($retbytes && $status) {
return $cnt; // return num. bytes delivered like readfile() does.
}
return $status;
}
을 다음 ReadFile을 문서에
대신 ReadFile을 긴 파일 FREAD를 사용하는 방법에 대한 예를 들어있어 :
function smartReadFile($location, $filename, $mimeType='application/octet-stream') {
if(!file_exists($location)) {
header ("HTTP/1.0 404 Not Found");
return;
}
$size=filesize($location);
$time=date('r',filemtime($location));
[email protected]($location,'rb');
if(!$fm) {
header ("HTTP/1.0 505 Internal server error");
return;
}
$begin=0;
$end=$size;
if(isset($_SERVER['HTTP_RANGE'])) {
if(preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)){
$begin=intval($matches[0]);
if(!empty($matches[1])){ $end=intval($matches[1]); }
}
}
if($begin>0||$end<$size){
header('HTTP/1.0 206 Partial Content');
}else{
header('HTTP/1.0 200 OK');
}
header("Content-Type: $mimeType");
header('Cache-Control: public, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Accept-Ranges: bytes');
header('Content-Length:'.($end-$begin));
header("Content-Range: bytes $begin-$end/$size");
header("Content-Disposition: inline; filename=$filename");
header("Content-Transfer-Encoding: binary\n");
header("Last-Modified: $time");
header('Connection: close');
$cur=$begin;
fseek($fm,$begin,0);
while(!feof($fm)&&$cur<$end&&(connection_status()==0)) {
print fread($fm,min(1024*16,$end-$cur));
$cur+=1024*16;
}
}
질문에 대답하지 않지만 큰 파일을 제공합니다. 아마도 https://tn123.org/mod_xsendfile/을 사용하여 웹 서버에 이메일을 남기는 것이 좋습니다. – deceze
@deceze 당신의 해답 **는 ** 질문에 대답합니다 (그리고 당신은 그런 식으로 공식화해야합니다)! 'mod-xsendfile'을 사용하면 Apache의 내부 구조를 사용하고 PHP 기반 솔루션보다 훨씬 뛰어난 안정성과 성능을 제공하므로 아래에 언급 한 답변보다 훨씬 낫습니다. 아파치 서버에서 스크립트가 실행되지 않거나'mod-xsendfile'을 사용하는 이유가 옵션이 아닌 경우에만 대답을 고려해야합니다. – trejder