2009-06-08 2 views
2

다음 스크립트는 사용자가 파일을 다운로드 할 수 있도록 대화 상자가 표시되도록 브라우저에서 헤더를 푸시하는 데 일반적으로 사용하는 스크립트입니다.외부 서버의 파일에서 헤더를 다운로드하는 방법은 무엇입니까?

그러나이 경우 파일은 다른 서버에 있습니다. 비록이 차이가 없어야하지만 externam MP3 파일의 URL로이 스크립트를 실행하면 "오류 : 파일을 찾을 수 없습니다"라는 메시지가 나타납니다. 그러나이 파일은 존재하며이 스크립트에 전달한 동일한 URL을 사용하여이 파일에 연결할 수 있습니다.

왜 그런가? 나는 어떤 도움을 주셔서 감사합니다.

<?php session_start(); 

//below variable contains full path to external site where file resides 
$filename = $_SESSION['$serverURL'].'audio/'.$_SESSION['fileName'].'.mp3'; 
//below variable contains a chosen filename of the file to be downloaded 
$properFilename = $_GET['properFilename'].'.mp3'; 

// required for IE, otherwise Content-disposition is ignored 
if(ini_get('zlib.output_compression')) 
    ini_set('zlib.output_compression', 'Off'); 

// addition by Jorg Weske 
$file_extension = strtolower(substr(strrchr($filename,"."),1)); 

if($filename == "") 
{ 
    //echo "download file NOT SPECIFIED"; 
    exit; 
} elseif (! file_exists($filename)) 
{ 
    //echo "ERROR: File not found"; 
    exit; 
}; 
switch($file_extension) 
{ 
    case "pdf": $ctype="application/pdf"; break; 
    case "exe": $ctype="application/octet-stream"; break; 
    case "zip": $ctype="application/zip"; break; 
    case "doc": $ctype="application/msword"; break; 
    case "xls": $ctype="application/vnd.ms-excel"; break; 
    case "ppt": $ctype="application/vnd.ms-powerpoint"; break; 
    case "gif": $ctype="image/gif"; break; 
    case "png": $ctype="image/png"; break; 
    case "jpeg": 
    case "jpg": $ctype="image/jpg"; break; 
    default: $ctype="application/force-download"; 
} 
header("Pragma: public"); // required 
header("Expires: 0"); 
header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
header("Cache-Control: private",false); // required for certain browsers 
header("Content-Type: $ctype"); 
// change, added quotes to allow spaces in filenames, by Rajkumar Singh 
header("Content-Disposition: attachment; filename=\"".basename($properFilename)."\";"); 
header("Content-Transfer-Encoding: binary"); 
header("Content-Length: ".filesize($filename)); 
readfile("$filename"); 
exit(); 

?> 

답변

3

단일 따옴표 문자열이 너무 $_SESSION['$serverURL'] 아마이 예상대로 작동하지 않을, 변수에 대한 구문 분석되지 않습니다. 나는 당신이 $_SESSION[$serverURL] 또는 $_SESSION['serverURL']을 의미하는 것으로 의심합니다.

filesize()을 호출 한 다음 readfile()을 호출하면 다른 서버에서 파일을 가져 오는 두 가지 HTTP 요청 (예 : 캐시되지 않은 경우)이 스크립트에서 발생합니다. 더 나은 옵션 일 수있는 cURL을 사용하여 하나의 HTTP 요청으로 할 수 있습니다. 간단한 예제가 있습니다. 원하는 것을하기 위해 그것을 적용 할 수 있어야합니다. Content-Type 헤더와 같은 다른 헤더를 직접 재 생성하지 않고 다른 서버 (신뢰할 수있는 경우)에서 전달하는 것도 고려할 수 있습니다.

<?php 

$ch = curl_init(); 

curl_setopt($ch, CURLOPT_URL, 'http://example.com'); 

//set callbacks to receive headers and content 
curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'on_receive_header'); 
curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'on_receive_content'); 

//send your other custom headers somewhere like here 

if (false === curl_exec($ch)) { 
    //handle error better than this. 
    die(curl_error($ch)); 
} 

function on_receive_header($ch, $string) { 
    //You could here forward the other headers received from your other server if you wanted 

    //for now we only want Content-Length 
    if (stripos($string, 'Content-Length') !== false) { 
     header($string); 
    } 

    //curl requires you to return the amount of data received 
    $length = strlen($string); 
    return $length; 
} 

function on_receive_content($ch, $string) { 
    echo $string; 

    //again return amount written 
    $length = strlen($string); 
    return $length; 
} 
+0

답장을 보내 주셔서 감사합니다. 나는 실제로 세션 변수로 실수를했다. 그것은 $ _SESSION [ 'serverURL']이어야합니다. 이 문제를 해결 한 후에도 같은 문제가 발생했습니다. 파일 크기를 보내는 줄도 제거했습니다. 그럼에도 여전히 효과가 없었습니다! – Abs

+0

파일이 있는지 조건부 검사를 제거했을 때 실제로 작동했습니다. 그리고 줄을 추가했습니다. ob_clean(); flush(); readfile(); 앞에; 귀하의 CURL 크기 게터를 구현하려고합니다. :) – Abs

관련 문제