UPDATE: PHP Download-counter Script

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.

 

Kommentar hinzufügen

E-Mail: Für Antworten. Wird nicht angezeigt.
  Sicherheitscode zur Prüfung. Nur Kleinschreibung. Keine Leerzeichen.
Kommentare (17)
unbekannte Fehler
05. Juli 2011
Pappandrero
Wie soll ich damit umgehen:

Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /mnt/web6/60/23/51093523/htdocs/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/download.php
doc/zip/test.zip

habe auch die download.php geändert:
Line 28 /** Downloadordner */
Line 29 public $folder = '.zip/';
Re: läuft :
19. April 2011
Dirk Hoeschen

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/octet-stream und schau mal hier. http://www.feenders.de/ratgeber/experten/398-download-von-dateien-erzwingen.html

läuft :D
18. April 2011
Danke, stimmt, hab irgendwie gepennt. Lag nur an den Rechten.
Mal was Anderes. Momentan nutze ich ja Zip-Dateien.
In 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).
Bei meinem Schnelltest (application/pdf´) 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
re: Anpassungen veröffentlichen
18. April 2011
Dirk Hoeschen
Hallo Eisbär, hallo PeterS,

danke für Deinen Code - ich kann den Sinn der Erweiterung (von Eisbär) aber nicht erkennen.

1: Der Downloadcounter ist Teil des Dateinamens. Ihn auszugeben ist kein Problem. Wofür also count.txt?
2: Sobald mehrere Dateien über das script downgeloadet würden, dann würden die Counter kollidieren weil alle auf die gleiche Datei zugreifen.

Ich werde das Script erweitern und eine Funktion zur Bidschirmausgabe des Downloadcounters einbauen.

mfg... Dirk
Re: kleine Probleme
18. April 2011
Joest Feenders
Hi ChrisZ,
hmmm - die Fehlermeldung gibt doch den Hinweis - Permission denied - überprüfe die Rechte in dem Ordner ...
Ciao Joest
kleine Probleme :D
16. April 2011
Ich muss vorab zugeben, dass ich mit php mal so garnichts am Hut habe. Ich benutze es nur für Sachen, die mit HTML nicht oder nur schwer möglich sind.
Nun wollte ich das Script hier ausprobieren und hab folgendes gemacht:
"download.php" erstellt, alles entfernt und nur den Scriptcode eingefügt. Neuen Unterordner "test" gewählt. Seite phptest.html (gleicher Ordner, wie "download.php") erstellt. Link "download.php?f=test.zip" erstellt.
"test.zip" im gewählten Unterordner"test" eigefügt.

Soweit müsste es nun ja meiner Theorie nach funktionieren ^^
Er findet die Datei zweifellos ja auch, scheint aber keine gibt mir aber nur diese Fehlermeldung:
Warning: rename(./test/test.zip,./test/0:0:test.zip) [function.rename]: Permission denied in /var/www/vhosts/meine-domain.de/httpdocs/test/download.php on line 15
weitere Fehlermeldungen dann natürlich in Zeile 25,33,34,35,36,36.

Vielleicht weiß ja einer was ich falsch gemacht habe :D
Anpassungen veröffentlichen
16. April 2011
Ist es möglich, dass die in den Kommentaren aufgezeigten Ergänzungen, im dargestellten script eingebaut werden?
Ich schaffe es leider nicht die Ergänzugen, insbesondere die Funktion mit dem Schreiben und der Ausgabe der counts, im oben aufgezeigten script selbst einzubauen.
Wäre dankbar, wenn jemand das hier veröffentlichen würde :)

Danke!
sehr gutes skript / 3
14. April 2011
ausgabe mit :

if(!file_exists("count.txt")){
$counter=fopen("count.txt", "a");
}
else{
$counter=fopen("count.txt", "r+");
}
$aufruf=fgets($counter,100);
rewind($counter);
fclose($counter);
echo $aufruf;
sehr gutes skript / 2
14. April 2011
so gehts :) ...
diesen teil einfach ersetzten ;)

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);
// Counter count.txt
if(!file_exists("count.txt")){
$counter=fopen("count.txt", "a");
}
else{
$counter=fopen("count.txt", "r+");
}
$aufruf=fgets($counter,100);
$aufruf=$aufruf+1;
rewind($counter);
fputs($counter,$aufruf);
fclose($counter);
break;
}

ausgabe mit :
sehr gutes skript
14. April 2011
finde ich gut das Skript aber mir fehlt die Funktion das man ausgeben kann wie oft eine Datei heruntergeladen wurde...
re: it doesn`t work
10. Januar 2011
Dirk Hoeschen

Sure it does! "f" ist just the name of the GET variable sent by the script. If your scriptname is "download.php"... ... and your filename is "test.zip" ... you call http://www.yourhost.com/download.php?f=test.zip The file test.zip must exist in a folder called "./downloads/" and it must be writable by the php script. If you want files with other extensions you must enhance the script. Anyway: this is just an example for programmers.

it doesn`t work
05. Januar 2011
what is f , I think something missing in your code , can you please gve us more details such as :
folder name how to call the script ...
re: Erweiterung mit Referalkontrolle
29. Oktober 2010
Joest Feenders

Hi ef,
danke für Feedback. Wir nutzen ähnliche Scripts aber auch z.B. für Downloadlinks per Email (z.B. in Shopanwendung für automatisierte Emails nach Bezahlung mit Downloadlink auf Software / eBooks etc.) - das würde mit Deiner Modifikation so nicht funktionieren ...
Ciao Joest

Erweiterung mit Referalkontrolle
28. Oktober 2010
Schöne Idee, mit dem folgendem Code wird noch der Refereal getestet, sodass der Downloadlink nicht von Fremdseiten benutzt werden kann, einfach oben einfuegen und anpassen

$path="downloads/files/";
$host = 'www.dein-host.de';

$ref = parse_url($_SERVER["HTTP_REFERER"]);
if(strtolower($ref['host']) != strtolower($host)) {
// Weiterleiten, zb zu Hilfeseite
header('Location: /');
exit;
}
frage zur einbettung
25. August 2010
hallo,
ich bin absoluter php neuling...
ich brauche für eine website einen downloadcounter und bin dann auf das script gestoßen.
bewirken will ich damit, dass sich der dateiname ändert +1 pro download und man das ergebnis quasi über ein backend aufrufen kann.
z.b. gebe ich hinter der domain "/pdf/ger" ein und sehe dann das verzeichnis und anhand der namen, wie oft die pdf's runtergeladen wurden.
jetzt meine frage: wie binde ich das denn jetzt in meine seite ein?
http://217.19.185.23/test2/solpower_html/page.html
Re: Danke
20. Juli 2010
Joest Feenders
Hi Waisenbach,
naja - so wie im Script angegeben schon. Aber mit minimaler Modifikation: -> header('Content-type: application/zip') - ziemlich am Ende des Scriptes - ist das ja leicht entsprechend Deinen Wünschen anzupassen ;-)
Ciao Joest
Danke....
19. Juli 2010
Wirklich nette Idee. Einfach und doch effektiv.

eins jedoch...

Das Beispiel funktioniert nur mit zip Archiven
 

Alexander Verlag - (Homepage & Webshop)
Im Juli 2010 haben wir das Dutzend erreicht. Mit dem Alexander... weiter

Der Fall Kurras und die Stasi - Microsite
Das erste Buch zum Fall des enttarnten Stasi-Spitzels Karl-Heinz... weiter

Facebookintegration für Verlage
Anhand des Gmeiner Verlages zeigen wir, welche Möglichkeiten... weiter