obiwan1973: Mit PHP Dateien im Browser anzeigen

Hallo,

ich schicke vorweg: Den Beitrag habe ich bereits in einem anderen Forum gepostet, aber leider ohne Erfolg.

Ich möchte mit PHP Dateien im Browser anzeigen, die in einem geschützen Bereich meines Webservers liegen (also auf keiner Webfreigabe).

Mit PDF-Dateien bekomme ich es prima hin, aber bspw. Word und Bilder werden einfach nicht angezeigt. Ich habe den Code stark vereinfacht, vielleicht hat ja jemand noch einen Tipp für mich:

  
  
$filefullpath = "C:\\test\\attachments\\cases\\17\\nur_ein_test.doc";  
  
$filesize = filesize($filefullpath);  
  
$filename = basename($filefullpath);  
  
header("Pragma: public");  
header("Expires: 0");  
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");  
header("Cache-Control: private", false);  
header("Content-Type: application/msword");  
header("Content-Disposition: inline; filename=\"". $filename . "\";");  
header("Content-Description: File Transfer");  
header("Content-Transfer-Encoding: binary");  
header("Content-Length: " . $filesize);  
  
readfile($filefullpath);  
  
  

Gruß

Tommy

  1. Hi,

    Ich möchte mit PHP Dateien im Browser anzeigen, die in einem geschützen Bereich meines Webservers liegen (also auf keiner Webfreigabe).

    Ob eine Datei im Browser angezeigt wird, kannst Du mit PHP nicht festlegen. Das ist allein Sache des Browsers und seiner Konfiguration.

    Mit PDF-Dateien bekomme ich es prima hin, aber bspw. Word und Bilder werden einfach nicht angezeigt.

    Sondern? Zum Speichern angeboten? In Word direkt angezeigt (also ohne Browser)? ...?

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
    1. Hi,

      Ich möchte mit PHP Dateien im Browser anzeigen, die in einem geschützen Bereich meines Webservers liegen (also auf keiner Webfreigabe).

      Ob eine Datei im Browser angezeigt wird, kannst Du mit PHP nicht festlegen. Das ist allein Sache des Browsers und seiner Konfiguration.

      Mit PDF-Dateien bekomme ich es prima hin, aber bspw. Word und Bilder werden einfach nicht angezeigt.

      Sondern? Zum Speichern angeboten? In Word direkt angezeigt (also ohne Browser)? ...?

      cu,
      Andreas

      Hallo Andreas,

      Word versucht verzweifelt, den Content zu interpretieren, schafft es aber nicht (es kommt ein Dialog zur Auswahl einer Kodierung und mit der Möglichkeit, die Datei lokal zu speichern).
      Egal, wie ich mich entscheide (Öffnen oder Speichern). Word kann den Inhalt nicht interpretieren. Dabei ist die Worddatei in Ordnung, aber 1a. Und ich habe sie auf demselben PC erstellt (ist eine Word2003-Datei mit der Endung *.doc).
      Wenn ich ein Bild anzeigen lassen will, kommt nur das Bild-Platzhaltersymbol (rotes Rechteck).

      Gruß

      Thomas

      1. Hallo Thomas

        Egal, wie ich mich entscheide (Öffnen oder Speichern). Word kann den Inhalt nicht interpretieren. Dabei ist die Worddatei in Ordnung, aber 1a. Und ich habe sie auf demselben PC erstellt (ist eine Word2003-Datei mit der Endung *.doc).

        Wenn Du Word-Dateien im Browser anzeigen willst, musst du sie als Webseite abspeichern.

        Beste Grüsse Richard

      2. Word versucht verzweifelt, den Content zu interpretieren, schafft es aber nicht

        ...

        Wenn ich ein Bild anzeigen lassen will, kommt nur das Bild-Platzhaltersymbol (rotes Rechteck).

        Dedlfix gab die richtige Antwort.

        Jörg Reinholz

  2. Hi,

    Ich möchte mit PHP Dateien im Browser anzeigen, ...

    das liegt, wie Andreas schon sagte, nicht in deiner Macht, sondern ist Sache dessen, der den Browser nutzt und nach seinen Wünschen konfiguriert.

    Mit PDF-Dateien bekomme ich es prima hin, aber bspw. Word und Bilder werden einfach nicht angezeigt. Ich habe den Code stark vereinfacht, vielleicht hat ja jemand noch einen Tipp für mich:

    Wenn du die Ressource mit wget herunterlädst, sind dann Originaldatei und heruntergeladene Datei identisch?
    Wenn du die Ressource mit dem Browser herunterlädst, sind dann Originaldatei und heruntergeladene Datei identisch?

    Vermutlich nicht, sonst gäbe es ja kein Problem. Vergleiche also "vorher" und "nachher" Byte für Byte, am besten mit einem Hex-Editor. Schau dir an, worin der Unterschied besteht. Vermutlich landet noch irgendwas vom Script her in der Ausgabe, was da nicht hingehört.

    Werden denn die Header tatsächlich richtig gesendet? Check mit Firebug, LiveHTTP-Extension oder ähnlichen.
    Falls nein: Macht dein Script vor dem hier gezeigten Code-Block schon eine Ausgabe? Vielleicht eine Leerzeile oder eine BOM?

    Ciao,
     Martin

    --
    Ich denke, also bin ich hier falsch.
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    1. Tach!

      Vermutlich nicht, sonst gäbe es ja kein Problem. Vergleiche also "vorher" und "nachher" Byte für Byte, am besten mit einem Hex-Editor. Schau dir an, worin der Unterschied besteht. Vermutlich landet noch irgendwas vom Script her in der Ausgabe, was da nicht hingehört.

      Ein weiterer Versuch wäre, als Content-Type mal text/plain anzugeben, dann zeigt der Browser das was er bekommt als Text an. Herauskommen muss dabei Binärmüll, aber manchmal sieht auch, dass PHP eine Fehlermeldung eingefügt hat.

      dedlfix.

  3. Hallo zusammen,

    ich habe es raus. Ist aber doch aufwändiger, als ich dachte.

    Beim Content-Type-Header muss man schon ein wenig differenzieren, je nachdem, was es für ein Dateityp ist. Aber ich habe mir den Aufwand gemacht, und das Ergebnis ist wirklich gut. Zwar öffnet sich die Word-Datei nicht - wie erhofft - im Browser, sondern der Browser fragt, was mit der Datei geschehen soll, aber egal.

    So sieht mein Code jetzt aus. Allen vielen Dank.

      
      
    if(file_exists($filefullpath))  
    {  
    	$filename = basename($filefullpath);  
    	//  
    	$filesize = filesize($filefullpath);  
    	//  
    	$separator = ".";  
    	//  
    	$check = explode($separator, $filename);  
    	//  
    	if(count($check) > 1)  
    	{  
    		$fileextension = strtolower($check[count($check) - 1]);  
    		//  
    		header('Content-Description: File Transfer');	  
    		//  
    		if($fileextension . "" === "pdf")  
    		{  
    			header("Content-Type: application/pdf");  
    		}  
    		elseif($fileextension . "" === "zip")  
    		{  
    			header("Content-Type: application/zip");  
    		}  
    		elseif($fileextension . "" === "doc")  
    		{  
    			header('Content-Type: application/octet-stream');  
    		}  
    		elseif($fileextension . "" === "docx")  
    		{  
    			header('Content-Type: application/octet-stream');  
    		}	  
    		//				  
    		header('Content-Disposition: inline; filename='.basename($filefullpath));  
    		header('Content-Transfer-Encoding: binary');  
    		header('Expires: 0');  
    		header('Cache-Control: must-revalidate');  
    		header('Pragma: public');  
    		header('Content-Length: ' . filesize($filefullpath));  
    		//  
    		ob_clean();  
    		//	  
    		flush();  
    		//	  
    		readfile($filefullpath);	  
    	}  
    }  
      
    
    

    Allen schon mal einen angenehmen Wochenausklang.

    Gruß aus der Schwäbischen Pampa (Sachsenheim)

    Thomas

    1. Om nah hoo pez nyeetz, obiwan1973!

      Gruß aus der Schwäbischen Pampa (Sachsenheim)

      Ich hab schon immer gewusst, dass Schwaben eigentlich in Sachsen liegt (die sagen da übrigens Vollscheibe).

      Matthias

      --
      Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Schaf und Schaffner.

    2. Tach!

      Zwar öffnet sich die Word-Datei nicht - wie erhofft - im Browser, sondern der Browser fragt, was mit der Datei geschehen soll, aber egal.

      Ach, gibt es denn Word als Plugin für Browser?

      So sieht mein Code jetzt aus.

      Teilweise unnötig ausführlich. Code breaks your Application. Deshalb ist es besser, auf entbehrliche Dinge zu verzichten.

      $filename = basename($filefullpath);
      $filesize = filesize($filefullpath);
      $separator = ".";
      $check = explode($separator, $filename);

      $filename und $separator werden ein einziges Mal verwendet. Warum dann nicht gleich das "." als Stringliteral der Funktion explode() übergeben, und basename($filefullpath) als zweiten Parameter? $filesize hast du gar nicht verwendet, es stattdessen gleich so geschrieben:

        header('Content-Length: ' . filesize($filefullpath));  
      

      Du brauchst die Dateigröße nicht am Anfang des Codes, also ermittle sie möglichst nicht so weit weg von ihrer Einsatzstelle. Du verlierst das nur aus den Augen - wie sich gezeigt hat.

      if(count($check) > 1)

      $check erklärt seine Bedeutung nicht. Was wird denn hier geprüft? Die Bedeutung muss man sich aus der Arbeitsweise des Programms ableiten. Dann weiß man aber nicht, ob das mit der Intention des Autors übereinstimmt. Sprechende Bezeichner könnten hier sehr beim Nachvollziehen helfen.

        $fileextension = strtolower($check[count($check) - 1]);  
      

      Und warum beginnt die Erweiterung beim erstbesten Punkt? Nimm doch pathinfo() zum Zerlegen des Dateinamens! - Hmm, Kollateralschaden auf meiner Seite beim Code-Lesen. Da hab ich doch ein substr() hineininterpretiert. Wie auch immer, ich empfehle stattdessen end($filename_parts), wenn $filename_parts das Ergebnis des explode() beinhaltet, oder strrchr($filefullpath, '.') (Ergebnis allerdings inklusive Punkt) oder das schon erwähnte pathinfo(), was du ja auch gleich noch für andere Zwecke verwenden könntest.

        if($fileextension . "" === "pdf")  
      

      $fileextension ist ein String. Hier noch einen Leerstring anzuhängen, ändert daran nichts. Welche Bewandnis hat die Typsicherheit beim Vergleich? Es gibt hier keinen Zweifel, dass du String mit String vergleichst. Ein Vergleich ohne Typüberprüfung tut's genauso und bringt exakt dasselbe Ergebnis.

        header('Content-Disposition: inline; filename='.basename($filefullpath));  
      

      Ah, hier unten kommt noch ein zweiter Kandidat für $filename, aber die Chance hast du ausgelassen.

        ob\_clean();  
        flush();  
        readfile($filefullpath);	  
      

      Die ersten beiden Anweisungen ergeben in dem Zusammenhang keinen Sinn. Wieso möchtest du denn den Ausgabepuffer leeren? Was ist denn da drin gelandet? Solltest du nicht besser dafür sorgen, dass gar nichts erst zur Ausgabe kommt? Und wenn nichts im Ausgabepuffer drin ist, was bringt dann ein Zwangsausgeben in Richtung Client? HTTP-Header senden? Das passiert sowie beim ersten Byte von readfile().

      if(file_exists($filefullpath))

      Gibts irgendwo noch eine Überprüfung, dass nur Dateien aus erlaubten Verzeichnissen abgefragt werden können?

      dedlfix.