PHP/Umgang mit HTTP-Headern

Aus Mikiwiki
< PHP
Zur Navigation springen Zur Suche springen

Typisch ist die Möglichkeit, eine Datei vom Webserver herunterzuladen. An sich ist das sehr einfach, jedoch bietet nicht jeder Webbrowser den Dialog zum Herunterladen an, einige versuchen die Datei stattdessen anzuzeigen. Das folgende Skript verhindert dies. Das Programm verwendet im wesentlichen die HTTP-Header, um die entsprechende Reaktion im Webbrowser auszulösen. Die Datei selbst wird mit den Dateifunktionen geladen.

<?php
error_reporting(0);
$file = @fopen($fileName, "r");
header("Content-Type: $application");
header("Content-Disposition: attachment; filename=$fileName");
header("Content-Description: PHP5 Generated Data");
header("Pragma: no-cache");
header("Expires: 0");
fpassthru($file);
fclose($file);
?>

Das folgende Beispiel verwendet denselben Mechanismus, doch diesmal werden Bilder zum Herunterladen angeboten. Klickt der Nutzer auf ein Bild, so wird dieses nicht erneut angezeigt, sondern geladen.

<?php
$command = isset($_GET['command']) ? (int) $_GET['command'] : 0;

if ($command == 1 && isset($_GET['filename']))
{
  $filename = $_GET['filename'];
  header("Content-Disposition: attachment; filename=$filename");
  header("Content-type: image/gif");
  header("Content-Length: ".filesize("$filename"));
  header("Pragma: no-cache");
  header("Expires: 0");
  $fp=fopen("$filename","r");
  print fread($fp, filesize("$filename"));
  fclose($fp);
  exit();
}

if ($command == 0)
{
  $filename = "data/download.gif";
  echo <<<HTML
    <body bgcolor="#eeeeee">
    <p>Klicken Sie auf das Bild, um es zu laden:</p>
    <p><a href="{$_SERVER['PHP_SELF']}?command=1&filename=$filename">
      <img src="$filename" border="0" width="400" height="300">
    </a></p>
HTML;
}
?>

Der ganze Effekt beruht auf den mit "header" gesendeten Kopfzeilen. Falls erforderlich, können weitere Funktionen zur Kontrolle des Vorgangs herangezogen werden:

Funktion Beschreibung
headers_sent Gibt einen booleschen Wert zurück, der anzeigt, ob bereits Header gesendet wurden. Mit Hilfe zweier optionaler Parameter, die beide Variablen sein müssen, wird Datei und Zeile des Ortes bestimmt, wo die Ausgabe begann. Der Zeitpunkt der Ausgabe ist entscheidend, weil nach dem ersten Zeichen des Inhalts zwangsläufig keine Header mehr gesendet werden können.
if (headers_sent($file, $line))
{
  echo "Ausgabe begann in $file auf Zeile $line.";
}
headers_list Gibt ein Array mit allen bisher erzeugten Kopfzeilen zurück und eignet sich damit gut zur Fehlersuche. Zur Ausgabe bietet sich die Funktion "var_dump" an.