Johann: Download-Script

Hallo,

ich habe ein einfaches Download-Script gefunden, was ich für meine Seite verwenden möchte.
Die Beschreibung war für meine nicht so guten PHP-Kenntnisse teilweise  nicht ausreichend.
Kann mir wer weiterhelfen ?
Die Zeilen mit den // davor sind originalbeschreibung
Originalscript:

// $download sei der Bezeichner für die zu ladende Datei
// etwa:
$download = $_GET['download'];

Frage 1: Soll ich also das Scipt, nennen wir es download.php, mit z.B. download.php?download=file2 aufrufen?

// Dieses Verzeichnis liegt außerhalb des Document Root und
// ist nicht per URL erreichbar.
$basedir = "/home/www/download";

Frage 2: Was heißt per URL nicht erreichbar? Ist damit gemeint das man einfach so nicht auf den Pfad kommt, oder soll das Verzeichnis irgendwie geschützt werden, z.B. mit .htaccess ?

// Übersetzung von Download-Bezeichner in Dateinamen.
$filelist = array(
  "file1" => "area1/datei1.zip",
  "file2" => "area1/datei2.zip",
  "file3" => "area2/datei1.zip"
);

// Einbruchsversuch abfangen.
if (!isset($filelist[$download]))
  die("Datei $download nicht vorhanden.");

// Vertrauenswürdigen Dateinamen basteln.
$filename = sprintf("%s/%s", $basedir, $filelist[$download]);

Frage 3: printf() kenne ich. das ist so wie echo(), bloß das die Ausgabe formatiert wird. Was aber soll das "s" davor?

// Passenden Datentyp erzeugen.
header("Content-Type: application/octet-stream");

// Passenden Dateinamen im Download-Requester vorgeben,
// z. B. den Original-Dateinamen
$save_as_name = basename($filelist[$download]);
header("Content-Disposition: attachment; filename="$save_as_name"");

Frage 4: Bedeutet die Zeile mit basename(), das der Dateiname aus dem Pfadnamen extrahiert wird und dann in $save_as_name geschrieben wird ? Wenn ja , wie erkennt dann der  nachfolgende header den richtigen Pfad ?

// Datei ausgeben.
readfile($filename);

mfg

Johann

  1. hi,

    Frage 1: Soll ich also das Scipt, nennen wir es download.php, mit z.B. download.php?download=file2 aufrufen?

    ==> KORREKT

    Frage 2: Was heißt per URL nicht erreichbar? Ist damit gemeint das man einfach so nicht auf den Pfad kommt, oder soll das Verzeichnis irgendwie geschützt werden, z.B. mit .htaccess ?

    ==> außerhalb des document_roots wird nix php geparst

    // Vertrauenswürdigen Dateinamen basteln.
    $filename = sprintf("%s/%s", $basedir, $filelist[$download]);

    Frage 3: printf() kenne ich. das ist so wie echo(), bloß das die Ausgabe formatiert wird. Was aber soll das "s" davor?

    ==> http://www.php.net/manual/de/function.sprintf.php

    mfg

    dito

    comunicout

    --
    fütter mein ego !
    welcome to electro-smog therapy
    1. Hallo,

      danke erstmal für die schnelle Antwort.

      ==> außerhalb des document_roots wird nix php geparst

      Ok, also soll das Verzeichnis in dem die Dateien liegen nicht Unterhalb des DocumentRoot-Pfades der Domain liegen ?

      mfg

      Johann

      1. das Verzeichnis in dem die Dateien liegen
        nicht Unterhalb des DocumentRoot-Pfades der Domain liegen ?

        wenn ich dich jetzt richtig verstanden habe dann "ja".
        doch ist dieses bereits gegeben wenn du dir deinen space besorgst..
        --
        solltest du das "upload-file" meinen, dann "nein". denn es ist
        wurscht von wo (welchem Ordner) du die datei uploaden lässt.. müsstest
        sie lediglich nachher aus dem temporären in einen ordner deiner
        page kopieren...

        mfg
        comunicout

        --
        fütter mein ego !
        welcome to electro-smog therapy
        1. Hallo

          solltest du das "upload-file" meinen, dann "nein". denn es ist

          Hm eigendlich is das ja ein downloadscript :-)

          mfg

          Johann

  2. Hallo Johann,

    $download = $_GET['download'];
    Frage 1: Soll ich also das Scipt, nennen wir es download.php, mit z.B. download.php?download=file2 aufrufen?

    so wie ich das Script verstanden habe, ja.

    $basedir = "/home/www/download";
    Frage 2: Was heißt per URL nicht erreichbar?

    du kannst die Dateien nicht über http://www.example.com/pfad/zu/datei.tld aufrufen.

    Ist damit gemeint das man einfach so nicht auf den Pfad kommt, oder soll das Verzeichnis irgendwie geschützt werden, z.B. mit .htaccess ?

    nein

    $filename = sprintf("%s/%s", $basedir, $filelist[$download]);
    Frage 3: printf() kenne ich. das ist so wie echo(), bloß das die Ausgabe formatiert wird. Was aber soll das "s" davor?

    sprintf() gibt einen String zurück ->http://de3.php.net/sprintf

    $save_as_name = basename($filelist[$download]);
    header("Content-Disposition: attachment; filename="$save_as_name"");
    Frage 4: Bedeutet die Zeile mit basename(), das der Dateiname aus dem Pfadnamen extrahiert wird und dann in $save_as_name geschrieben wird ?

    ja

    Wenn ja , wie erkennt dann der  nachfolgende header den richtigen Pfad ?

    was meinst du damit? für was soll bei filename=... der Pfad drinstehen?

    Grüße aus Nürnberg
    Tobias

    --
    Selfcode: sh:( fo:) ch:? rl:( br:< n4:& ie:% mo:| va:) de:] zu:) fl:( ss:| ls:[ js:|
    1. Hallo,

      header("Content-Disposition: attachment; filename="$save_as_name"");

      was meinst du damit? für was soll bei filename=... der Pfad drinstehen?

      Soweit ich das verstanden habe ist der header dazu da den Speicher-Dialog des Browsers aufzurufen.
      Das filename beinhaltet doch aber nachdem der Dateiname extrahiert wurde (basename()) nur noch den Namen, nicht mehr den Pfad.
      Wie kann es also downgeloaded werden ?

      mfg

      Johann

      1. Hallo Johann,

        header("Content-Disposition: attachment; filename="$save_as_name"");
        was meinst du damit? für was soll bei filename=... der Pfad drinstehen?
        Soweit ich das verstanden habe ist der header dazu da den Speicher-Dialog des Browsers aufzurufen.

        afaik schägt der header nur einen Dateinamen vor (der Speicher-Dialog wird von 'header("Content-Type: application/octet-stream");' ausgelöst (allerdings kann dir der IE da - je nach Dateiart - einen Strich durch die Rechung machen - der kümmert sich nämlich um Content-Typen herzlich wenig))

        Das filename beinhaltet doch aber nachdem der Dateiname extrahiert wurde (basename()) nur noch den Namen, nicht mehr den Pfad.

        der header schickt nicht die Datei an den Browser - das macht erst readfile()

        Grüße aus Nürnberg
        Tobias

        --
        Selfcode: sh:( fo:) ch:? rl:( br:< n4:& ie:% mo:| va:) de:] zu:) fl:( ss:| ls:[ js:|
  3. Hallo,

    ich habe das script jetzt funktionsfähig.
    Aufruf ist z.B.
    <a href="javascript:window.open('download.php?download=123','download','width=1,height=1,resizable=no,scrollbars=no,title=download');">
    Javascript-Popup habe ich deshalb genommen, da das fenster nachher geschlossen werden soll.
    Download startet, aber leider schließt sich das Fenster danach nicht, woran kann das liegen ?

    <?
    $download = $_GET['download'];
    $basedir = "/downloadordner/";
    $filelist = array(
      "123" => "lalala.zip"
    );
    if (!isset($filelist[$download]))
      die("Datei $download ist nicht vorhanden.");
    $filename = sprintf("%s/%s", $basedir, $filelist[$download]);
    header("Content-Type: application/octet-stream");
    $save_as_name = basename($filelist[$download]);
    header("Content-Disposition: attachment; filename="$save_as_name"");
    readfile($filename);
    ?>
    <html>
    <head>
    <title>Download</title>
    <script language="JavaScript">
    <!--
    self.focus();
    self.close();
    //-->
    </script>
    </head>
    <body>
    </body>
    </html>

    1. Hallo Johann,

      ich habe das script jetzt funktionsfähig.

      das script ist von http://dclp-faq.de/q/q-datei-download.html, oder? :-)

      <a href="javascript:window.open('download.php?download=123','download','width=1,height=1,resizable=no,scrollbars=no,title=download');">

      warum dürfen leute ohne js die keine Dateien runterladen?
      besser (wenns schon unbedingt ein Popup sein muss) so:
      <a href="download.php?download=123" onclick="window.open(this.href,'download','width...'); return false;">...</a>
      btw: width/height=1 wird nicht überall funktionieren ->siehe Archiv

      Download startet, aber leider schließt sich das Fenster danach nicht, woran kann das liegen ?

      weil du keine html-Seite ausgibst und somit das js nicht ausgeführt wird.
      als Content-Type hast du schließlich application/octet-stream und nicht text/html - html ist in der Ausgabe der Datei download.php fehlt am Platze.

      <script language="JavaScript">

      hier fehlt das Attribut type

      Grüße aus Nürnberg
      Tobias

      --
      Selfcode: sh:( fo:) ch:? rl:( br:< n4:& ie:% mo:| va:) de:] zu:) fl:( ss:| ls:[ js:|
      1. Hallo,

        ich habe das script jetzt funktionsfähig.
        das script ist von http://dclp-faq.de/q/q-datei-download.html, oder? :-)

        joups

        warum dürfen leute ohne js die keine Dateien runterladen?

        Da is vorher schon ein Browsercheck der Leute ohne JS halt nicht auf die Seite läßt(jaja ich weiß BÖSE), weil die hauptsächlich aus einer großen JS-Popup-Gallerie besteht.

        btw: width/height=1 wird nicht überall funktionieren ->siehe Archiv

        Thx wußte ich gar nicht. Ab wieviel pixel funktioniert das dann überall.

        weil du keine html-Seite ausgibst und somit das js nicht ausgeführt wird.
        als Content-Type hast du schließlich application/octet-stream und nicht text/html - html ist in der Ausgabe der Datei download.php fehlt am Platze.

        Hm stimmt. Haste einen anderen Vorschlag wie ich nachher kein weiteres offenes Fenster da habe und auch dieselbe Seite angezeigt wird wie vorher ?

        Ach und mein Mozilla meint, das er den filye type nicht kennt.

        mfg

        Johann