2 Stimmen

Wie kann man Header aus einer Datei auf einem externen Server zum Download anbieten?

Das folgende Skript verwende ich in der Regel, um Kopfzeilen an den Browser zu senden, damit das Dialogfeld für das Herunterladen einer Datei erscheint.

In diesem Fall befindet sich die Datei jedoch auf einem anderen Server. Ich dachte, das sollte keinen Unterschied machen, aber das tut es, denn wenn ich dieses Skript mit der URL einer externen MP3-Datei ausführe, bekomme ich eine "ERROR: Datei nicht gefunden". Die Datei existiert jedoch, und ich kann sie über dieselbe URL aufrufen, die ich dem Skript übergebe.

Irgendwelche Ideen, warum? Ich wäre für jede Hilfe dankbar.

<?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();   

?>

3voto

Tom Haigh Punkte 56080

Strings in einfachen Anführungszeichen werden nicht für Variablen analysiert, so dass $_SESSION['$serverURL'] wird wahrscheinlich nicht so funktionieren, wie Sie es erwarten. Ich vermute, Sie meinen $_SESSION[$serverURL] o $_SESSION['serverURL'] .

Auch anrufen filesize() und dann readfile() wird wahrscheinlich dazu führen, dass Ihr Skript zwei HTTP-Anfragen stellt, um die Datei vom anderen Server zu holen (es sei denn, sie wird irgendwie zwischengespeichert). Sie könnten eine einzige HTTP-Anfrage mit cURL durchführen, was vielleicht eine bessere Option wäre. Hier ist ein kurzes Beispiel, das Sie so anpassen können, dass es Ihren Wünschen entspricht. Sie könnten auch in Betracht ziehen, andere Header wie den Content-Type-Header vom anderen Server weiterzuleiten (falls zuverlässig), anstatt sie selbst neu zu generieren.

<?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;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X