Manchmal will man einfach nur zählen, wie oft ein Programm oder ein Archiv heruntergeladen wird. Häufig will man auch verhindern, dass ein direkter Download von einer fremden Seite möglich ist. Ein erstaunlich kurzes Script schafft Abhilfe.

UPDATE

Wir haben uns die Zeit genommen und das Script zu einer ordentlichen Klasse ausgebaut, die auf Wunsch auch die Anzahl der bereits erfolgten Downloads ausgibt und den direkten Aufruf von einer Seite außerhalb der eigenen Domain verhindern kann.

Das Paket einfach herunterladen und in einem Webordner enpacken. Im Paket findet sich auch ein Beispiel, das den Einbau in eigene Dateien zum Kinderspiel machen sollte.

Nicht vergessen!! der "./downloads" Ordner und die darin enthaltenen Dateien müssen durch PHP lesbar und schreibbar sein.

Das PHP Script

PHP Download Counter
<?php
/*
* Downloadcounter Kontrollscript
* Author Dirk Hoeschen (hoeschen at feenders.de)
*/

$path="./downloads/";
// hole dateinamen aus variable f
$f = @strip_tags($_GET['f']);
if ($f!="") {
// ganzes verzeichnis lesen
$dir_handle = @opendir($path) or die("Unable to open ".$path);
while ($file = readdir($dir_handle)) {
if (!is_dir($file)) {
if ($file==$f) {
rename($path.$file,$path."0:0:".$file);
$file = "0:0:".$file;
}
// datei in array splitten
$fparts = preg_split('/:/',$file);
if ((count($fparts)>1) && ($fparts[2]==$f)) {
// counter+1, zufallswert ermitteln, datei umbenenenn
$dlcount = intval($fparts[0])+1;
$frandom = hash("md5",microtime());
$newfilename=$dlcount.":".$frandom.":".$f;
rename($path.$file,$path.$newfilename);
break;
}
}
}

// datei mit dem ursprünglichen namen ausgeben
if (isset($newfilename) && ($newfilename!="")) {
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="'.$f.'"');
header("Content-Transfer-Encoding: binary");
readfile($path.$newfilename);
}

}

?>

 

Wie funktioniert es?

Dem Downloadscript wird über die Variable "f" (http://www.webseite.php/download.php?f=test.zip) der gewünschte Dateiname übermittelt. Das Script sucht nun im Unterordner "downloads" nach der Datei. Die Datei ist nach folgendem Muster gespeichert: ZÄHLER:HASH:DATEINAME.

Die Teile zwischen dem ":" werden aufgesplittet. Der Zähler wird um eins erhöht, ein neuer Hashwert generiert und die Datei umbenannt.

Dadurch ist ein Download der Datei nur über das Script möglich. Zusätzlich kann man über den Dateinamen ermitteln, wie oft die Datei heruntergeladen wurde. Das Script funktioniert nur mit ZIP-Dateien. Bei anderen Dateitypen muss es ergänzt werden.

Zugriffsbeschränkung

Bis jetzt funktioniert unser Script nur als Zähler. Außerdem verhindert es den direkten Download.

Wenn das Script in einem passwortgeschützten Bereich liegt oder über die Sessionvariable auswertet, ob ein Benutzer angemeldet ist, kann es leicht dazu dienen, dass ein Download nur nach einer vorherigen Benutzeranmeldung möglich ist.

Kommentare  

#24 Stresstestholzfaeller 2017-02-15 17:17
Hi,

zuerst: vielen Dank für den Beitrag, vor allem für die Erklärung des Ablaufs.

Hat schon jemand einen Stresstest gemacht? Wie verhält sich das Script, wenn gleichzeitig mehrere User die selbe Datei anfordern?

Ich vermute eine logische Lücke: solange der Download eines Users aktiv ist, kann die Datei nicht umbenannt werden.

holzfaeller
Zitieren
#23 Verbesserungsvo rschlagSamet Tarim 2016-10-22 13:45
Ich wollte Verbesserungsvo rschläge machen, leider haben die Zeichen fürs kommentar nicht gereicht.

$f = strip_tags(trim (filter_input(I NPUT_GET, 'f'))); // Am besten noch htmlspecialchar s benutzen mit UTF-8 muss man gucken wie man das vorher gehandelt hat

// $f = @strip_tags($_G ET['f']); // Auf globale sollte man nicht direkt zugreifen und bin kein fan von @ operatoren die fehler unterdrücken

// File typ ermitteln
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$type = finfo_file($fin fo, $path . $newfilename); // inder schleife setzen wo der $path . $newfilename pfad ermittelt wurde
finfo_close($finfo);

header('Content-type: ' . $type); // dann im header unten den type übergeben

// Mit den downloads füllen
$whitelist = array (); // Bevor
if (!is_dir($file) ) { // Hier nach
array_push($whitelist, $file); // Hinzu

// Prüfen
if(in_array($f, $whitelist)) { // DOWNLOAD } else { // unerlaubt }
Zitieren
#22 variable PfadangabeDetlef Teichmann 2014-04-18 11:17
Hallo,
das Script funktioniert zuverlässig - danke dafür! Allerdings bräuchte ich eine Möglichkeit, auf die (gleichen) Downloaddateien von verschiedenen Unterordnern zugreifen zu können. Also: Script liegt in ./_dlcounter, die Dateien in ./_dlcounter/do wnloads. Zugreifen möchte ich auf abc.zip einmal von ./1/2/ und einmal von ./1/2/3/ aus. Entweder findet das Script abc.zip erst gar nicht oder der Counter wird nicht angezeigt. Leider reichen meine Kenntnisse nicht aus, um die Klasse entsprechend zu modifizieren (also so, dass ich von jedem Verzeichnis der Website auf den zentralen Downloadordner zugreifen kann und auch der Counter richtig angezeigt wird).
Ist Hilfe möglich?
Zitieren
#21 dlcounterchris mitch 2014-02-26 19:38
Hallo,

möchte auf der selben php seite noch ein zweites Programm zum downloaden anbieten,
jedoch nimmt er mit nur die erste .zip datei und zählt diese hoch, die zweite wird ignoriert...

Erste Datei




***********

Zweite
Datei
Zitieren
#20 Zwei kleine Anpassungen, jetzt läuft es super. Danke 2013-12-14 09:30
Ein klasse Script... kurz und knackig. Es erfüllt alle meine Vorstellungen. Danke für das kostenlos Script. Jetzt kann ich die Downloads einfach zählen. Gott segne Dich!
Zitieren
#19 Fehler in dlcounter.zip 2013-12-07 16:44
Hi, ich wollte kurz anmerken, dass in dem script ein Fehler ist (bzw. im Archiv). Nämlich wird im script nach '::' getrennt, die Testdatei ist aber nach '__' getrennt. Mi t freundlichen Grüßen
Zitieren
#18 Klasse, kompakt und funktionell... 2013-11-11 17:32
Vielen Danke für das kleine Script. Genau so etwas brauche ich gerade...
Zitieren
#17 unbekannte Fehler 2011-07-05 21:01
Wie soll ich damit umgehen: Par se error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /mnt/web6/60/23 /51093523/htdoc s/doc/download. php on line 29 Er bricht auch direkt an dieser Stelle im Code den Seitenaufbau ab... hab eine php-Seite "wasgibts.php" von wo aus man eine ZIP-Datei "test.zip" runterladen soll: Ordnerstruktur: doc/wasgibts. php doc/downlo ad.php doc/zip /test.zip ha be auch die download.php geändert: Line 28 /** Downloadordner */ Line 29 public $folder = '.zip/';
Zitieren
#16 Re: läuft : 2011-04-19 10:29

application/ pdf ist ja genau das, was du nicht haben willst. Dadurch weiß der Browser, dass es ein PDF ist und versucht den Acrobat-Reader im Fenster zu starten. Versuchs mal mit application/oct et-stream und schau mal hier. http://www.feenders.de/ratgeber/experten/398-download-von-dateien-erzwingen.html

Zitieren
#15 läuft :D 2011-04-18 16:35
Danke, stimmt, hab irgendwie gepennt. Lag nur an den Rechten. Mal was Anderes. Momentan nutze ich ja Zip-Dateien. I n diesen befindet sich eigentlich nur eine Gleichnamige PDF-Datei. Da es bei der Größe von rund 500kb kaum einen relevanten Unterschied macht, würde ich die Daten eigentlich gerne gleich als PDF zum Download zur Verfügung stellen. Diese sollen aber auch tatsächlich runtergeladen werden und nicht im neuen Fenster geöffnet werden (um den Traffic zu minimieren). B ei meinem Schnelltest (application/pd f´) entstand jedoch nur ein leerer Bildschirm. Vielleicht kann mir dabei noch jemand behilflichs ein. Vielen Dank auf jeden Fall für die Hilfe. Gruß ChriZ
Zitieren

Kommentar schreiben


Sicherheitscode
Aktualisieren