Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   [PHP] Download-Counter (https://www.delphipraxis.net/64619-%5Bphp%5D-download-counter.html)

MisterNiceGuy 6. Mär 2006 10:50


[PHP] Download-Counter
 
Hi ich möchte gerne auf meiner Homepage einen Downloadcounter mit MySQL die Zugriffe auf bestimmte Dateien zählen lassen.
Allerdings würde ich das gerne so programmieren, dass ich nicht eine neue Seite laden muss um einen Download zu starten z.B. so
Code:
download.php?id=1
Ich will stattdessen den Counter in den Link einzufügen z.B. so
Code:
[url="./Programme/Einkaufsliste_setup.exe"]Einkaufsliste_setup.exe[/url]
Vielleicht lässt sich das mit Java Script machen? Ich hab leider keine Ahnung :(
Wenn ich den PHP-Quellcode direkt in den Link schreibe, wird der Wert des Counters auch beim Betreten der Seite erhöht.

alcaeus 6. Mär 2006 10:56

Re: [PHP] Download-Counter
 
Moin,

du musst das ueber eine extra-Seite machen, wenn du es nicht von client-seitigen Scripts abhaengig machen willst.
Du kannst ja den Link auf die Extra-Seite verweisen lassen, dort updaten, Download-Header senden, und dann die Datei per readfile() an den Client senden. Funktioniert bei mir auch einwandfrei ;)

Greetz
alcaeus

Hador 6. Mär 2006 11:04

Re: [PHP] Download-Counter
 
Das wirst du so wohl nicht hinbekommen, da du mit JavaScript keine Daten speichern kannst.
Und da PHP eine Serverseitige Scriptsprache ist, ist dabei nix mit Benutzerinteraktion.

Daher brauchst du eine Zwischenseite.
Allerdings muss der Benutzer davon nichts merken.

Du musst einfach folgendes machen:

Code:
<?
if (isset($_GET['file'])) {  // $_GET['file'] ist der Dateiname
  // Den passenden Wert in der Datenbank erhöhen
  header('Location: downloads/'.$_GET['file']); // Auf die Datei weiterleiten
}
?>
Is zwar 'n roter Kasten da, aber ich poste das dennoch mal so

MisterNiceGuy 6. Mär 2006 12:13

Re: [PHP] Download-Counter
 
Danke für eure Antworten :) Ich hab es in der Zwischenzeit mal mit einem Java-popup probiert, aber das wird von meinem Browser schon geblockt.

Werd jetzt die nächste Methode ausprobieren.
@Hador: Den Quellcode packe ich in eine neue PHP-Datei oder? Ich nehme mal nicht an, dass die dann neu geöffnete Seite dann nicht geschlossen wird, wie kann ich das noch realisieren?

SubData 6. Mär 2006 12:37

Re: [PHP] Download-Counter
 
Anderweitig kannst du natürlich folgendes machen:

Code:

<script>
function CountDownload(id, datei)
{
 location.href = '/count.php?id=' + id;
 window.setTimeout('location.href=\'' + datei + '\'', 1000);
}
</script>

[url="#"]Datei[/url]
Wichtig dabei ist, dass die PHP Seite KEINE Ausgabe erzeugt, also quasi 0 Byte zurückliefert.
Wenn dies der Fall ist wird die Seite nicht verlassen und der zweite Script-Part (window....) wird ebenfalls
ausgeführt. So werden beide Dateien nacheinander aufgerufen.

Markus 6. Mär 2006 12:47

Re: [PHP] Download-Counter
 
Also ich mache das ganze so:

Datei "download.php":
Code:
<?php
if ($_GET[id] != "")
{
        $query = "UPDATE downloads SET anzahl = anzahl + 1 WHERE id = '".intval($_GET[id])."'";
        $result = mysql_query($query);

        $query = "SELECT dateiname FROM downloads WHERE id = '".intval($_GET[id])."'";
        $datei = mysql_fetch_array(mysql_query($query));
        $datei = $datei[dateiname];
       
        if ($datei != "")
        {
            $filename = $_SERVER[DOCUMENT_ROOT]."/downloads/".$datei;

            header("Content-Type: application/octet-stream");
            header("Content-Disposition: attachment; filename=\"$datei\"");
            readfile($filename);
        }
    }
}
?>
Wenn du dann noch eine .htaccess ins Download-Verzeichnis reinpackst, die folgendes enthält:
Code:
Order Allow, Deny
Allow from localhost
Deny from all
kannst du noch verhindern, dass die Downloads direkt aufgerufen werden. Das ist zwar eine neue Seite, aber diese Seite stellt im Prinzip den Download dar, daher ist das kein Problem.

Keine Garantie, dass es genauso funkioniert, hab nur meine kurz umgeschrieben :-)

Matze 6. Mär 2006 12:50

Re: [PHP] Download-Counter
 
@Markus: Du solltest noch ein

Code:
mysql_free_result($result);
einbauen. ;)

Markus 6. Mär 2006 12:51

Re: [PHP] Download-Counter
 
Jo, sollte, mach ich aber nie :-) Aber hast natürlich recht... :D

MisterNiceGuy 6. Mär 2006 13:01

Re: [PHP] Download-Counter
 
Also ich hab das jetzt so geregelt:
Code:
<? 
if (isset($_GET['download'])) {   
  switch ($_GET['file']) {                         
    case 1:header('Location: Programme/EMail_Checker_setup.exe');    
...
    case 28:header('Location: Programme/MrOnline_zip.zip');
  } 
  $db_link = @mysql_connect("localhost", "web89", "*****");            
  mysql_select_db("usr_web89_1");
  $dlid=$_GET['download'];
  mysql_query("UPDATE dlcounter Set counter = counter+1 WHERE id=$dlid");          

?>
<script type= "text/javascript" >
self.close();
</script>
Die Variable in der Datenbank wird erhöht, aber weder der Download startet, noch wird das Fenster am Ende geschlossen. Wer weiß warum da passiert bekommt 'nen Kuchen :)

[edit=alcaeus]Datenbankpasswort entfernt! :warn: Mfg, alcaeus[/edit]

Markus 6. Mär 2006 13:03

Re: [PHP] Download-Counter
 
Probier mal
Code:
case "1"
statt
Code:
case 1

MisterNiceGuy 6. Mär 2006 13:11

Re: [PHP] Download-Counter
 
Holla, PW hab ich grad vorsichtshalber geändert :)

Aber der Script startet immernoch keinen Download.

vlees91 6. Mär 2006 13:36

Re: [PHP] Download-Counter
 
Zitat:

Zitat von Matze
@Markus: Du solltest noch ein

Code:
mysql_free_result($result);
einbauen. ;)

wozu ist das notwendig?
man setzt normale variablen ja auch net zurück

PS: sry für ot

[edit=alcaeus]Uebermaessige Verwendung des color-Tags entfernt. In Zukunft solche Schwachsinnigkeiten bitte unterlassen! :warn: Mfg, alcaeus[/edit]

MisterNiceGuy 6. Mär 2006 13:46

Re: [PHP] Download-Counter
 
@Markus: Lies readfile nicht eine Datei ein? Wenn ich deine Methode einbaue, fängt mein Browser an zu haken. Scheint ziemlich prozessorlastig zu sein ;)

S2B 6. Mär 2006 13:50

Re: [PHP] Download-Counter
 
@vlees91: Kommt darauf an, wie groß eine Variable ist... :wink:

pacman1986 6. Mär 2006 14:23

Re: [PHP] Download-Counter
 
@vlees91
warum schreibst du bunt ???

ebenfals sry für ot :P

Daniel 6. Mär 2006 14:35

Re: [PHP] Download-Counter
 
So, nun wieder zurück zum Thema bitte.

Mystic 6. Mär 2006 14:43

Re: [PHP] Download-Counter
 
Es lässt sich sogar fast komplett transparent gestalten:

Ein Verzeichnis (z.B. /files), welches nur eine .htaccess enthält:
Code:
RewriteEngine on
RewriteBase   /files/
RewriteRule   ^(.+)$ /download.php\?file=$1
Alle Anfragen à la /files/Datei123.exe werden dann intern nach /download.php?file=Datei123.exe umgeleitet. Das Skript kann dann den Counter für die Datei erhöhen und die echte Datei123.exe an den Client weiterleiten ( readfile() ).

Meine download.php:

Code:
<?php
  $filename = 'realfiles/' . $_GET['file'];
  if (IsSet($_GET["file"]) && file_exists($filename) && strpos($filename,'../') === false)
  {
    require 'dblogin.php';
    $dbh = mysql_login();
    mysql_select_db('danny');
    $stats_query = "SELECT count FROM downloads WHERE file='" . $_GET['file'] . "'";
    $stats_result = mysql_query($stats_query);
    if (mysql_num_rows($stats_result) > 0)
    {
      $stats_array = mysql_fetch_assoc($stats_result);
      if ($stats_array['count'] !== null)
      {
        $stats_query = "UPDATE downloads SET count = count + 1 WHERE file='" . $_GET['file'] . "'";
        mysql_query($stats_query);
      }
    }
    mysql_close($dbh);
    header('Content-type: application/force-download');
    header('Content-length:' . filesize($filename));
    readfile($filename);
  } else {
    header('Status: 404 Not Found');
    chdir('errors');
    require '404.php';
  }
?>

vlees91 6. Mär 2006 16:54

Re: [PHP] Download-Counter
 
So ists auch gut finde ich
ich habs bisher immer wie oben genannt gemacht:
liste mit allen downloads in eine db (incl. downloadzahl)
dann über download.php?a=123 die zahl in der db aktualisiert
und die download.php schickt die datei automatisch zum user



OT: wie setzt man denn eine variable in PHP zurück?

[edit=alcaeus]Uebermaessige Verwendung des color-Tags entfernt. In Zukunft solche Schwachsinnigkeiten bitte unterlassen! :warn: Mfg, alcaeus[/edit]

Nicolai1234 6. Mär 2006 17:14

Re: [PHP] Download-Counter
 
Zitat:

Zitat von Mystic
Es lässt sich sogar fast komplett transparent gestalten:

Ein Verzeichnis (z.B. /files), welches nur eine .htaccess enthält:
Code:
RewriteEngine on
RewriteBase   /files/
RewriteRule   ^(.+)$ /download.php\?file=$1
Alle Anfragen à la /files/Datei123.exe werden dann intern nach /download.php?file=Datei123.exe umgeleitet. Das Skript kann dann den Counter für die Datei erhöhen und die echte Datei123.exe an den Client weiterleiten ( readfile() ).

Meine download.php:

Code:
<?php
  $filename = 'realfiles/' . $_GET['file'];
  if (IsSet($_GET["file"]) && file_exists($filename) && strpos($filename,'../') === false)
  {
    require 'dblogin.php';
    $dbh = mysql_login();
    mysql_select_db('danny');
    $stats_query = "SELECT count FROM downloads WHERE file='" . $_GET['file'] . "'";
    $stats_result = mysql_query($stats_query);
    if (mysql_num_rows($stats_result) > 0)
    {
      $stats_array = mysql_fetch_assoc($stats_result);
      if ($stats_array['count'] !== null)
      {
        $stats_query = "UPDATE downloads SET count = count + 1 WHERE file='" . $_GET['file'] . "'";
        mysql_query($stats_query);
      }
    }
    mysql_close($dbh);
    header('Content-type: application/force-download');
    header('Content-length:' . filesize($filename));
    readfile($filename);
  } else {
    header('Status: 404 Not Found');
    chdir('errors');
    require '404.php';
  }
?>

Sorry, ich fange gerade erst wieder an mich mit php &mysql zu beschäftigen... Was muss den in diesem fall in der "dblogin.php" alles drinstehen? Ich bekomm das gerade nicht ganz auf die Reihe...

Tubos 6. Mär 2006 17:19

Re: [PHP] Download-Counter
 
Vorrausgesetzt, die Datei macht nicht mehr als den Datenbank-Login: Dann müsste es sich um zwei Funktionsaufrufe handeln.
mysql_connect mit Benutzername und Passwort zum Verbinden und mysql_select_db zum Auswählen der Datenbank.

MisterNiceGuy 6. Mär 2006 20:41

Re: [PHP] Download-Counter
 
Ich hab jetzt eine meiner Meinung nach ganz schöne Lösung gefunden :)

Code:
<?php  
  switch ($_GET['file']) { 
    case 1:$NewHeader="EMail_Checker_setup.exe"; break;
    ...
    case 28:$NewHeader="MrOnline_zip.zip"; break;
  } 
  header('Location: Programme/'.$NewHeader);
  $db_link = @mysql_connect("localhost", "***", "***");            
  mysql_select_db("usr_web89_1");
  $dlid=$_GET['download'];
  mysql_query("UPDATE dlcounter Set counter = counter+1 WHERE id=$dlid");
?>
Dabei wird die jeweilige Fileid und die Downloadid übergeben, bespielsweise mit einem Aufruf wie diesem:
Code:
[url]www.schnick.de/hallo.php?file=1&download=2[/url]

himitsu 7. Mär 2006 12:53

Re: [PHP] Download-Counter
 
Und warum nimmst du nicht die FileID gleich mit als DownloadID?
Dann hast du die gleiche ID in der DB und PHP(switch).

Außerdem vergiß das intval nicht, da man dir sonst über die ID($dlid) ganz netten Code in die DB einschleusen könnte :zwinker:

Code:
<?php  
  switch ($_GET['file']) {
    case 1:$NewHeader="EMail_Checker_setup.exe"; break;
    ...
    case 28:$NewHeader="MrOnline_zip.zip"; break;
  } 
  header('Location: Programme/'.$NewHeader);
  $db_link = @mysql_connect("localhost", "***", "***");            
  mysql_select_db("usr_web89_1");
  $dlid=intval($_GET['file']);
  mysql_query("UPDATE dlcounter Set counter = counter+1 WHERE id=$dlid");
?>
www.schnick.de/hallo.php?file=1


Und wenn du nicht ständig an der PHP und der DB rumspielen willst, wenn du was hinzigefügt/gelöscht/geändert hast, dann mach doch alles in die DB, also
ID | Dateiname | Counter


Ach ja, es macht sich auch nicht schlecht, wenn du noch prüfst, ob es die gewünschte ID überhaupt gibt.

MisterNiceGuy 7. Mär 2006 13:08

Re: [PHP] Download-Counter
 
Naja ich hab immer ein Setup und eine Zip von jedem Programm. Ich biete also 28 Downloads an, aber ich zähle nicht jede einzelne Datei im Counter sondern jedes Programm. Deswegen 2 Variablen.

Das mit dem intval wusste ich nicht, danke ;)

himitsu 8. Mär 2006 10:30

Re: [PHP] Download-Counter
 
Zitat:

Zitat von MisterNiceGuy
Das mit dem intval wusste ich nicht, danke ;)

Büdde :)

Zitat:

Zitat von MisterNiceGuy
Naja ich hab immer ein Setup und eine Zip von jedem Programm. Ich biete also 28 Downloads an, aber ich zähle nicht jede einzelne Datei im Counter sondern jedes Programm. Deswegen 2 Variablen.

Also dafür gäbe es 2 mindestens Lösungen ...
entweder man rechnet die Counter der beiden Dateien bei der Ausgabe/Auswertung zusammen (hat aber zwei Counter),

oder man könnte natürlich immernoch Runden und dergleichen
Code:
<?php  
  switch ($_GET['file']) {
    case 0: $NewHeader = "EMail_Checker_setup.exe"; break;
    case 1: $NewHeader = "EMail_Checker_zip.zip"; break;
    ...
    case 26: $NewHeader = "MrOnline_setup.exe"; break;
    case 27: $NewHeader = "MrOnline_zip.zip"; break;
  }
  header('Location: Programme/'.$NewHeader);
  $db_link = @mysql_connect("localhost", "***", "***");
  mysql_select_db("usr_web89_1");
  mysql_query("UPDATE dlcounter Set counter = counter+1 WHERE id=" . [i][b](intval($_GET['file']) & ~1)[/b][/i]);
  @mysql_close($db_link);
?>
Also
Datei 0 und 1 = Counter 0
Datei 2 und 3 = Counter 2
Datei 4 und 5 = Counter 3
...


oder wie wäre es mit dividieren °_°
Code:
  mysql_query("UPDATE dlcounter Set counter = counter+1 WHERE id=" . [i][b]floor(intval($_GET['file']) / 2)[/b][/i]);
?>
Also
Datei 0 und 1 = Counter 0
Datei 2 und 3 = Counter 1
Datei 4 und 5 = Counter 2



Ach ja, wenn du eh nicht die DB wieder schließt, dann brauchst du auch nicht die Verbindungs-Kennung in $db_link zu speichern ;)

MisterNiceGuy 8. Mär 2006 11:09

Re: [PHP] Download-Counter
 
Tja man merkt wohl, dass ich noch ziemlich neu in diesem Metier bin :)
Also Frage: Wenn ich 1 durch 2 Teile, was bekomme ich bei PHP für ein Ergebnis? 1? Das wäre ja ideal!
Hatte ich auch anfangs drüber nachgedacht, aber wieder verworfen, da ich mir nicht im Klaren darüber war, was diese Rechnung ergeben würde.

Die Datenbank schiließen? Mach ich doch glatt :)

himitsu 8. Mär 2006 11:24

Re: [PHP] Download-Counter
 
1 / 2 = 0.5

also abgerundet (floor) = 0, oder aufgerundet (ceil) = 1 :zwinker:

und gerundet (round) ... weiß gerade nicht, oder PHP im gegensatz zu Dlphi mathematisch korret rundet, aber 0.5 sollte wohl auch 1 ergeben :?:

xaromz 8. Mär 2006 11:25

Re: [PHP] Download-Counter
 
Hallo,
Zitat:

Zitat von MisterNiceGuy
Wenn ich 1 durch 2 Teile, was bekomme ich bei PHP für ein Ergebnis? 1? Das wäre ja ideal!

Nö, Du bekommst 0.5. Durch floor() rundest Du nach unten ab -> Null.

Gruß
xaromz


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:54 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz