Impressum · Kontakt · Hilfe
Besucher online · Mitglieder



Portal > Foren > Ankündigungen, News und Feedback > Tutorials > [PHP] Download-Skript, Downloads mit download.php?id=x
Antwort
 
Themen-Optionen
Alt 28.11.2005, 16:28   Nach oben    #1
Corvin
Erfahrener Benutzer
 
Benutzerbild von Corvin
 
Registriert seit: 19.03.2005
Ort: S-H | Flensburg
Beiträge: 439
Standard

Download-Skript, Downloads mit download.php?id=x

1. Worum geht es hier und wozu das Ganze?
Bisher sahen die Links zu deinen Downloads sicherlich etwa so aus:
Code:
http://www.example.com/downloads/datei.ext
In diesem Tutorial wird erklärt, wie man es anstellt, dass die Links zu den Downloads etwa so aussehen:
Code:
http://www.example.com/download.php?id=x
Diese Variante hat folgende Vorteile gegenüber der bisherigen:
  1. Es können bestimmte Referer geblockt oder nur bestimmte zugelassen werden.
    Es kann zum Beispiel eingestellt werden, die Downloads von allen Seiten verlinkt werden dürfen, außer von www.schlechteseite.de. Genauer: Wenn ich hier jetzt einen Download von deiner Website verlinkt funktioniert alles wunderbar und die Datei wird heruntergeladen. Wenn der Download nun aber auf www.schlechteseite.de verlinkt wird, soll eine Fehlermeldung ausgegeben werden.
  2. Es kann eine Datei verlinkt werden, ohne, dass der Benutzer erfährt, wo genau sich die Datei auf eurem Webserver/Webspace befindet.
  3. Es kann getestet werden, ob die Datei, die heruntergeladen werden soll überhaupt existiert/erreichbar ist. Wenn dies nicht der Fall ist, kann eine festgelegte Fehlermeldung ausgegeben werden.
  4. Es können auch Bilder, HTML-Dateien usw. so verlinkt werden, dass das "Speichern-Unter-Fenster" erscheint, anstatt dass sie angezeigt werden.

2. Wie das ganze funktioniert
Es wird eine Datei "download.php", nennen wir sie mal "Download-Skript" angelegt. Diese Datei enthält in einem Array alle Dateinamen, der Dateien, die zum Download bereitgestellt werden sollen. Jedem Dateinamen wird eine eigene ID zugewiesen. Wenn nun ein Download verlinkt werden soll sieht der Link wie folgt aus:
Code:
http://www.example.com/download.php?id=x
Das Download-Skript holt sich nun den Wert von id aus dem URL, dieser Wert ist die ID des Downloads. Nun weiß das Download-Skript welche Datei heruntergeladen werden soll und öffnet für diese das "Speichern-Unter-Fenster", ohne dass der genaue Pfad der Datei preisgegeben wird.

3. Der Grundbau des Download-Skripts
Hier nun der Grundbau des Download-Skripts, welchen wir nach und nach erweitern werden:
PHP-Code:
<?php
/*
 * Der Ordner indem sich die Dateien befinden
 */
$download_dir "Downloads/";

/*
 * Die herunterladbaren Dateien:
 */
$files = array(
                
"1" => "test.html",
                
"2" => "text.txt",
                
"3" => "doc.pdf",
                
"4" => "bild3.jpg",
              );

/*
 * Den kompletten Pfad der Datei (+Dateiname) in $file speichern
 */
$file $download_dir.$files[$_GET['id']];

/*
 * Header-Einstellungen
 */
header("Content-Type: x-type/subtype");
header("Content-Length: ".filesize($file));
header("Content-Disposition: attachment; filename=".$files[$_GET['id']]);

/*
 * Das "Speichern-Unter"-Fenster erscheinen lassen
 */
readfile($file);
?>
Die Dateien die zum Download verlinkt werden sollen, werden in dem Array $files gespeichert. Es können hier beliebig viele Dateien hinzugefügt werden. Einfach eine neue Zeile nach dem folgendem Shema hinzufügen:
Code:
"id" => "dateiname.ext",
Hierbei ist darauf zu achten, dass jede ID nur einmal vorkommt. Man kann natürlich auch folgendes schreiben:
PHP-Code:
<?php
$files
[] = "datei.ext";
$files[] = "datei2.ext";
//...
?>
Dies ist allerdings viel unübersichtlicher und es ist schwer die ID der Datei zu erkennen.

Zusätzlich habe ich noch einige header()-Befehle verwendet:
Code:
header("Content-Type: x-type/subtype");
Hiermit wird der passende Dateityp erzeugt, in diesem Fall x-type/subtype.
Code:
header("Content-Length: ".filesize($file));
Hiermit wird die Dateigröße (in Byte) angegeben.
Code:
header("Content-Disposition: attachment; filename=".$files[$_GET['id']]);
Hiermit wird der Browser gezwungen, das "Speichern-Unter-Fenster" anzuzeigen.

4. Prüfen, ob die Datei, die heruntergeladen werden soll existiert/erreichbar ist
Um zu überprüfen, ob die zu herunterladende Datei überhaupt existiert bzw. erreichbar ist, reichen vier Zeilen Code aus, diese schreiben wir vor die header()-Befehle:
PHP-Code:
<?php
if(!file_exists($file)) {
    echo 
"Die Datei existiert nicht bzw. ist nicht erreichbar!!";
    exit();
}
?>
5. Bestimmten Seiten das verlinken von Downloads verbieten
Erweitern wird das Download-Skript nun so, dass man beliebig vielen Seiten das Verlinken von Downloads verbieten kann.
Dazu legen wir zuerst ein Array an, in dem die URLs der Seiten gespeichert werden:
PHP-Code:
<?php
$sites 
= array(
                
"banned",
                
"http://www.schlechteseite.de",
                
"http://foo.bar.com",
                
"http://www.petras-seite.de",
                
"http://www.nochwas.de"
               
);
?>
Was das erste Array-Element ("banned") zu bedeuten hat erkläre ich im nächsten Abschnitt, ignoriert dies ersteinmal.

Nun brauchen wir noch eine Funktion, die die Prüfung durchführt:
PHP-Code:
<?php
function test_banned($sites$referer) {
    for(
$i=1;$i<count($sites);$i++) {
        if(
$sites[$i] == $referer) {
            return 
true;
        }
    }
}
?>
Die Funktion vergleicht jedes (bis auf das erste bzw. 0-te) Array-Element mit dem in $referer enthaltenen String. Wenn ein String in $sites gefunden wird (also der Seite von der der Benutzer kommt das Verlinken nicht gestattet ist) gibt die Funktion true zurück.
Damit die Funktion die gewünschten Ergebnisse leifert, muss die Variable $referer natürlich noch zugewiesen werden, die folgenden Zeilen müsst du vor die header()-Befehle und vor die gleich kommende if-Abfrage schreiben:
PHP-Code:
$referer explode("/"$_SERVER['HTTP_REFERER']);
$referer $referer[0] ."//" .$referer[2];
?> 
Hier wird der Referer "auseinandergebaut" und anschließend wird nur der Domainname der Variable $referer zugewiesen.
Zum Beispiel wird aus http://www.seite.tld/einordner/datei.ext einfach http://www.seite.tld.
Das ganze könnte man natürlich auch mit preg_replace() machen, die Variante mit explode() ist aber schneller.

So und jetzt brauchen wir noch die Abfrage, die die Funktion test_banned() aufruft und anschließend von dem Rückgabewert abhängige Anweisungen ausführt:
PHP-Code:
<?php
if ($sites[0] == "banned") {
    
$test test_banned($sites$referer);
    if (
$test == true) {
        echo 
"Referer nicht zugelassen";
        exit();
    }
} else {
    die(
"Fehler in \$sites!!");
}
?>
Keine Angst, für den Fall, dass hier wer durcheinander kommt, habe ich das komplette Skript als Datei angehängt.

6. Nur bestimmten Seiten das verlinken von Downloads erlauben
Das Download-Skript jetzt so zu erweitern, dass man nur bestimmten Seiten das Verlinken von Downloads erlauben kann (und allen anderen verbieten) ist nun auch kein großer Sprung mehr, da das genauso wie im vorigen Abschnitt funktioniert, nur mit dem Unterschied, dass nun geprüft wird, ob die Seite, von der der Benutzer kommt, den Download verlinken durfte (und nicht, ob sie es nicht durfte). Du musst lediglich die if-Abfrage aus dem vorigen Kapitel erweitern:
PHP-Code:
<?php
if ($sites[0] == "banned") {
    
$test test_banned($sites$referer);
    if (
$test == true) {
        echo 
"Referer nicht zugelassen!!";
        exit();
    }
} elseif (
$sites[0] == "allowed") {
    
$test test_banned($sites$referer);
    if (
$test != true) {
        echo 
"Referer nicht zugelassen!!";
        exit();
    }
} else {
    die(
"Fehler in \$sites!!");
}
?>
Hier wird nun auch deutlich, was es mit dem erstem Array-Element von $sites auf sich hat: Wenn der Wert "banned" ist, werden alle Referer bis auf die in $sites gespeicherten zugelassen. Wenn der Wert "allowed" ist, werden alle Referer nicht zugelassen, außer die in $sites gepspeicherten.
Achtung! In letzterem Fall nicht vergessen, deine eigene Seite in $site einzutragen.

7. Abschließende Überlegungen
Das Download-Skript ist jetzt natürlich noch recht undynamisch, wenn man sehr oft neue Downloads zur Verfügung stellen und eventuell auch alte löschen will ist es sehr nervig, ständig die Datei download.php bearbeiten zu müssen. Viel komfortabler wäre es natürlich, die Dateinamen/Pfade in einer Datenbank zu speichern. Das solltest du aber selbst entscheiden, ob sich diese Funktion für dich lohnt, es wird hier auch nicht weiter darauf eingegangen, da das hier ein Tutorial für ein Download-Skript und nicht eines für das Arbeiten mit irgendeiner Datenbank ist.

Noch eine kleine Anmerkung: Da hier mit readfile() gearbeitet wird, können nur Dateien verwendet werden, die das, in der php.ini festgelegte, Speicherlimit nicht überschreiten. Die Einstellung in der php.ini heißt memory_limit und ist standardmäßig auf 8M (7,8125KB) gestellt.

8. Verwendete Funktionen/Befehle
array()
header()
filesize()
filesize()
explode()
readfile()
file_exists()

Und hier gibt's ein Tutorial zu Kontrollstrukturen: Tutorial zu Kontrollstrukturen.

Geändert von Jann Hendrik (27.06.2007 um 11:21 Uhr). Grund: intern-tag-Fehler manuell angepasst
Corvin ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist An.
Smileys sind An.
[IMG] Code ist An.
HTML-Code ist Aus.
Trackbacks are An
Pingbacks are An
Refbacks are Aus

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Wie erfolgreiche Downloads zählen? chgozdz PHP-Programmierung 11 20.07.2007 16:15


Alle Zeitangaben in WEZ +2. Es ist jetzt 06:59 Uhr.

Nach oben
Wir nutzen das Zend Framework, vBulletin (vBulletin v3.7.2, Copyright ©2000-2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.0.0) und vBSEO.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44