Bilder ohne "speichern unter" downloaden

Wer Gafiken, Wallpapers oder einfache Fotos einfach per Klick als Download anbieten möchte wird merken, dass es gar nicht so einfach ist. Ja, der Weg mit "rechte Maustaste" - "speichern unter" funktioniert zwar, wirkt aber nicht sehr professionell. Ein möglicher Weg wäre natürlich auch die Grafik in ein ZIP-Archiv zu packen. Nur wegen einer Grafikdatei gleich ein Zip File zu machen ist auch nicht sehr professionell.

Mit ein paar PHP-Codezeilen schaffen wir den besseren Weg mit der man eine Grafik direkt Downloaden kann. Wie das geht zeige ich hier.


Beispiel 1 - einzelne JPG Datei downloaden

Wir haben eine Grafik mit dem Namen "testbild.jpg", die wir mit einem einfachen Textlink zum Downloaden anbieten möchten.
Im gleichen Verzeichnis (Ordner) in der diese Grafik gespeichet ist, erstellen wir eine PHP Datei mit dem Namen "download.php mit folgendem Inhalt:

<?php
  header('Content-type: image/jpg');
  header('Content-Disposition: attachment; filename="testbild.jpg"');
  readfile('testbild.jpg');
?>

Nun müssen wir nur noch den Link zur "download.php"" auf der Webseite einbauen, wo der Downloadlink stehen soll. Hier schreiben wir einfach:

    <a href="/download.php" title="Download" />Download</a>

Natürlich muss je nach Verzeichnisstruktur die URL angepasst werden.

Resultat würde dann so aussehen: Download


Beispiel 2 - mehrere GIF Dateien einzeln downloaden

Wir haben mehrere GIF Dateien im Unterordner "images" liegen, die wir alle mit separaten Links zum Download anbieten möchten. Dazu erstellen wir zunächst eine PHP Datei, geben ihr den Namen "download.php" und speichern diese im gleichen Unterverzeichnis. Der Inhalt dieser "download.php" schaut folgendermaßen aus:

<?php
  $img=$_GET['img'];
  header('Content-type: image/gif');
  header('Content-Disposition: attachment; filename="'.$img.'.gif"');
  readfile($img.'.gif');
?>

Die Downloadlinks müssen die Namen der Grafikdateien als GET-Variable übergeben.

    <a href="/images/download.php?img=testbild1" title="Download 1" />Download Bild 1</a><br />
    <a href="/images/download.php?img=testbild2" title="Download 2" />Download Bild 2</a><br />
    <a href="/images/download.php?img=testbild3" title="Download 3" />Download Bild 3</a>

Natürlich muss je nach Verzeichnisstruktur die URL angepasst werden.

Resultat würde dann so aussehen:

Download Bild 1
Download Bild 2
Download Bild 3


Beispiel 3 - unterschiedliche Grafiktypen downloaden

Wir haben unterschiedliche Grafik Dateien im Unterordner "images" liegen. Eine "testbild.gif", eine "testbild.jpg" und eine "testbild.png" Datei.
Wir erstellen wieder eine PHP Datei, geben ihr den Namen "download.php" und speichern diese im gleichen Unterverzeichnis. Der Inhalt dieser "download.php" schaut jetzt folgendermaßen aus:

<?php

  $img=$_GET['img'];
  $type = mime_content_type($img);
  
  switch ($type) {
    case "image/gif":
      header('Content-type: image/gif');
      header('Content-Disposition: attachment; filename="'.$img.'"');
      readfile($img);
      break;
      
    case "image/jpeg":
      header('Content-type: image/jpeg');
      header('Content-Disposition: attachment; filename="'.$img.'"');
      readfile($img);
      break;
    
    case "image/png":
      header('Content-type: image/png');
      header('Content-Disposition: attachment; filename="'.$img.'"');
      readfile($img);
      break;
  }
  
?>

Die Downloadlinks müssen die Namen der Grafikdateien als GET-Variable übergeben. Dieses mal aber auch mit der Extension.

    <a href="/images/download.php?img=testbild.gif" title="Download GIF" />Download GIF-Bild</a><br />
    <a href="/images/download.php?img=testbild.jpg" title="Download JPG" />Download JPG-Bild</a><br />
    <a href="/images/download.php?img=testbild.png" title="Download PNG" />Download PNG-Bild</a>

Natürlich muss je nach Verzeichnisstruktur die URL angepasst werden.

Resultat würde dann so aussehen:

Download GIF-Bild
Download JPG-Bild
Download PNG-Bild

  • Samstag, 18 Februar 2012

Kommentare (2)

  • David Losse

    David Losse

    03 Juli 2012 at 20:19 |
    Danke für den netten Kommentar in anderen Artikel, ich helf ja gerne deswegen auch hier von mir noch einige Hinweise..

    Beispiel 1 ist okay, ich würde jedoch noch den Content -Lenght rein coden, vorteilhaft wenn es sich um MB Große Bilder > 3 MB

    header("Content-Length: ".filesize('testbild.jpg'));

    handelt, Mehr Pixel desto größer denn an einer UMTS Leidung bzw DSL Nutzer mit einer langsamen Download Geschwindigkeit würden raten wie groß die datei ist, da für keinen Internetznutzer eine Dateigröße angezeigt werden, ich finde es vorteilhafter wenn jeder weiss wie viel er noch zu laden hat.

    Beispiel 2 würde ich ehr meiden wollen, ich bin jetzt kein Hacker oder so nur ich weiss nicht ob Hacker über die Webadresse sich PHP Dateien beschaffen können oder ob .gif am ende es absichert.
    auch hier fehlt die Content-Length, $_GET Parameter sind nicht sauber im Quellcode das kann an anderen stellen zu Scriptproblemen u.a. Cookies führen, wenn durch ein Fehler bereits eine ausgabe z.B. einer Notice oder Error Apache-PHP Meldungen erfolgte.

    //Frei gecoded möglicherweise Tipp- oder Klammerfehler! kein if vergessen
    $img = (isset($_GET['img'])?$_GET['img']:false);
    if($img === false || ($img !== false && file_exists($img) === false)) die("Bild nicht ladbar");

    Was ich im 2. Beispiel unsicherer einstufe ist kann ich hier im 3. Beispiel als sicherer einstufen, da der Mime Typ (Datentyp) vom Server ermittelt wird und somit im case Zweig einen php Code nicht ladbar macht, da php nicht als Content Type image/.... gewertet wird. Auch hier fehlt der Prüf zweig für img.
    z.B. fürde die funktion mime_content_type() einen Fehler aufrufen, wenn dem System die Datei nicht bekannt ist, auch wenn die Fehlermeldungen durch display_error oder abgeschalteter error_reports auf 0 ist. is_readable() wäre auch noch eine gute Funktion um die Premission zu prüfen.

    z.B. eine Bild von Beispiel 2 was nicht exitiert

    Warning: readfile(******** [function.readfile]: failed to open stream: No such file or directory in /www/htdocs/w****154/demos/php-schnipsel/images_download_2/download.php on line 5

    Für den Fall das es wie hier eine Usereingabe ist preg benutzen!!!

    a-zA-Z0-9 oder selbst anderweitig prüfen..

    Beispiel 3 könnte kürzer gehen. :D
    switch ($type) {
    case "image/gif":
    case "image/jpeg":
    case "image/png":
    header('Content-type: '.$type);
    header('Content-Disposition: attachment; filename="'.$img.'"');
    header('Content-Length: '.filesize($img));
    readfile($img);
    break;
    }

    ich schreib mir doch nicht die Fingerwund, wenn der type eh schon vorhanden ist und doch nur auf den geprüft wird ^^ Die length hab ich auch schon reingemacht.. 50% weniger Zeilen ;-) er springt erst mit dem break aus dem case..

    Würde hier zwei arten sein, müsste man nen break vor setzen, mal ein Beispiel an monate

    checkDate($d,$m,$y) {
    switch($m) {
    case 1: case 3: case 5: case 7: case 8: case 10: case 12:$maxd = 31; break;
    case 2: // hier code zur berechnung für schaltjahre da februar
    break;
    case 4: case 6: case 9: case 11: $maxd = 30; break;
    }
    }

    hoffe es ist klar was ich meine?
    • Günther Hörandl

      Günther Hörandl

      03 Juli 2012 at 20:58 |
      Wow! Ich sehe schon, ich kann von dir noch ne Menge lernen.
      Vielen Dank für deine guten Überlegungen und Tipps!

Bitte Kommentar schreiben

Bitte einloggen, um einen Kommentar zu schreiben.