2009-06-08 10 views
2

次のスクリプトは、ユーザーがファイルをダウンロードするためのダイアログボックスが表示されるように、通常はヘッダーをブラウザにプッシュするために使用します。外部サーバー上のファイルからヘッダーをダウンロードするにはどうすればいいですか?

ただし、この場合、ファイルは別のサーバーに存在します。私はこれは違いはありませんが、externam MP3ファイルのURLでこのスクリプトを実行すると "ERROR:File not found"というメッセージが表示されます。ただし、このファイルが存在し、このスクリプトに渡したのと同じ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()を呼び出すと、おそらく(これは何とかキャッシュされますしない限り)他のサーバーからファイルを取得するには、2つのHTTPリクエストを作成スクリプトになります。 cURLを使用して1つの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