Force download a file automatically and keeping statistics with PHP

Many times when we go to download software we click the vendor’s download link on their site and are immediately taken to a download page where it says “the download will start immediately, if not please click this link.” So how do we actually go about doing this?

There is a lot of cool things we can do with this as appose to directly linking to the file we want our customer/visitor to download. A couple bonuses:

  • We can mask the download link so the visitor doesn’t know where the actual file resides
  • We can keep statistics on the visitors that download our file

The first thing we need is a download confirmation page. Any HTML will do. The one thing we need though is a redirect to our download script. Add this into your HEAD tag:

<meta http-equiv="refresh" content="1;URL=http://www.domain.com/download_file.php">

This will attempt to load http://www.domain.com/download_file.php after 1 second. Make sure you change http://www.domain.com/download_file.php to the actual location of your download file. You can change the 1 to whatever you wish. Remember that the unit is in seconds.

Now where all the work is done.

Here is download_file.php
//connect to our database
include_once('dbconnect.inc.php');

//log download
$sql = sprintf("INSERT INTO download_stats (d_ipaddr, d_browser, d_referer) VALUES ('%s','%s','%s')",
		mysql_real_escape_string($_SERVER['REMOTE_ADDR']),
		mysql_real_escape_string($_SERVER['HTTP_USER_AGENT']),
		mysql_real_escape_string($_SESSION["referer"])
		);
@mysql_query($sql);

//path to the file to download relative to the scripts execution dir
$file = 'files/download.zip';

//check if the file exists
if (file_exists($file)) {

    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="file.zip"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
   
   	ob_clean();
    flush();
    readfile($file);
    ob_clean();
    flush();
	exit;

}

The first thing we do is log the download into our database to keep track of the IP (can use this to find location), User Agent (can use to calculate browser stats), and the referrer string. I have it set to $_SESSION["referer"] because I store any external referrer link in this so I can keep track of what site the visitor came to my site from. If you just want the last page they were on, use $_SERVER["HTTP_REFERER"].

Now on to the download code. We set $file as the file path on our server we want to download relative our current download_file.php script. Now we check to make sure the file exists then output the headers to the browser that tell it were starting a file transfer. A couple notes about the headers:

  • file.zip can be changed to anything we want the download file to be named.
  • The Content-Type header is dependent of the type of file you are serving. See this list for the different MIME types

Now for the finished product check out something like Skype.

This script was adapted directed from the PHP Manual.

Continue Reading

  • No Related Posts
  • http://62k.pl Strony www Kalisz

    Thank you very much!
    That’s all i needed – it works perfect!