5

I'ld like to count file downloads with PHP. The downloads number should be stored in a .TXT file.

How that can be done? Thanks Uli

Uli
  • 2,625
  • 10
  • 46
  • 71
  • 2
    Do you need it for just one file or more? – MartyIX Aug 27 '11 at 10:28
  • Yes, just for one file. (It's a .zip file) – Uli Aug 27 '11 at 11:12
  • Related: http://stackoverflow.com/questions/146/how-do-i-track-file-downloads-with-apache-php - I particularly like grep'ing the access.log – DanMan Aug 27 '11 at 11:12
  • I've edited the code to include an initial variable initialization that was previously rendered invisible by the code formatter. Also, I changed the $count++ to ++$count, in order to increment **before** writing and also treated the initial case when no file yet exists. – luvieere Aug 27 '11 at 11:50

2 Answers2

12
$current_count = file_get_contents('count');
$f = fopen('count', 'w+');
fwrite($f, $current_count + 1);
fclose($f);

header("Location: file.zip");
genesis
  • 50,477
  • 20
  • 96
  • 125
  • what about if the file download get's interrupted ? It will also count ad download ? – daslicht Aug 09 '18 at 13:31
  • @daslicht Yes, it will count as a download. What the code does is 1) increases a counter 2) redirects a user to the file to be downloaded. If a user chooses not to press 'save' or 'download' after prompted, it will still be counted in as if they would download it. – FanaticD Jul 08 '19 at 09:16
10

Create a file named, say, download.php, with the following content:

<?php
 $Down=$_GET['Down'];
?>

<html>
 <head>
  <meta http-equiv="refresh" content="0;url=<?php echo $Down; ?>">
 </head>
 <body>

 <?php

  $filePath = $Down.".txt";

  // If file exists, read current count from it, otherwise, initialize it to 0
  $count = file_exists($filePath) ? file_get_contents($filePath) : 0;

  // Increment the count and overwrite the file, writing the new value
  file_put_contents($filePath, ++$count);

  // Display current download count
  echo "Downloads:" . $count;
 ?> 

 </body>
</html>

Put a link to it in another page, with the file to be downloaded as a parameter:

download.php?Down=download.zip

Answer reference Dreamincode answer to a similar question

Community
  • 1
  • 1
luvieere
  • 37,065
  • 18
  • 127
  • 179
  • This looks great but the counter isn't working. Anything I missed? The .txt file starts with "0" counts and a CHMOD 777. – Uli Aug 27 '11 at 11:34
  • @Uli What should exactly do after creating download.php file? – Ali Vojdanian Dec 07 '14 at 22:15
  • 1
    Be careful, if you have your website in the internet! Everbody could download everthing from your server with this solution. – knobli Jan 17 '15 at 11:41
  • @knobli That is not true - this implementation only puts redirect between link to the file and actual file, AFAIK no new security risks are introduced. – FanaticD Mar 17 '17 at 23:55
  • what about if the file download get's interrupted ? It will also count ad download ? – daslicht Aug 09 '18 at 13:31
  • @FanaticD The file that gets downloaded is determined by the $get which in turn, is determined by the URL. An attacker could just modify the URL to get whatever file whose filename they could guess or see. Genesis's solution shown below is more secure. – Michael Jul 07 '19 at 18:05
  • @Michael In my original comment, I was wrong. There are additional issues introduced. But you are still not quite correct about where they are. There is a reflected XSS (rendering unsanitized input from URL directly into the page) and an unvalidated redirect. You and @knobli are misunderstanding how `meta refresh` works though. An attacker can modify the URL to whatever file they want, but it will not force the download of that file. It will only redirect the user to that file (if the file is let's say .php, **it will not be downloaded**, but executed). – FanaticD Jul 08 '19 at 09:11
  • @Michael If you'd like to discuss this more, we can do so in [chat.stackoverflow.com](https://chat.stackoverflow.com/rooms/11/php) (PHP room). – FanaticD Jul 08 '19 at 09:22