PHP Download Files and Log: Serve local and remote files for download

Recommend this page to a friend!
  Info   View files Example   View files View files (7)   DownloadInstall with Composer Download .zip   Reputation   Support forum (1)   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2021-01-11 (4 months ago) RSS 2.0 feedNot enough user ratingsTotal: 282 All time: 7,497 This week: 277Up
Version License PHP version Categories
dnlclass 0.9Freeware5HTTP, PHP 5, Files and Folders, Logging
Description Author

This class can be used to serve local and remote files for download and log the download activity.

It can take the number of a local file and serve it for download by reading the file contents from a file from a download directory with and the path is the same as the file number.

The class can also serve files for download reading them from remote server given the respective file URL.

The details of the files that are download are logged to files, or database records or sent by email, or a combination of these log storage methods.

The class can detect if the current request is coming from a robot or a Web crawler script so it avoids serving files for these requests.

Innovation Award
PHP Programming Innovation award nominee
May 2020
Number 2
Many sites need to serve files for download but if the files are directly accessible by whoever needs them, users many use scripts to automate downloading and end up overloading the Web site server.

This package provides an alternative solution to serve files for download without disclosing the real file paths on the local or remote server to avoid that scripts can access the files directly.

It can also detect when a file is being downloaded by a robot and refuses to serve the file in that case, thus avoiding to overload the server.

The class can detect if the current request is coming from a robot or a Web crawler script, so it avoids serving files for these requests.

Manuel Lemos
Picture of Pierre FAUQUE
  Performance   Level  
Name: Pierre FAUQUE <contact>
Classes: 15 packages by
Country: France France
Age: 74
All time rank: 16011 in France France
Week rank: 18 Up2 in France France Up
Innovation award
Innovation award
Nominee: 9x

Winner: 1x


                class.dnl.php's User Guide
                 version 0.2 - 07/05/2020

class.dnl.php is a PHP class allowing to download files located
on your website or anywhere else and to log these downloads
into logfiles, by email or into a database or by combining
several of these possibilities.
This class can be used by your webserver, not your FTP server.

It does not replace the logfiles of your web server which will
continue to runs normally but allows you to log the download
of special files that you want to have a look on.

The download service contains 3,4 and maybe 5 files :
- the class.dnl.php (class which can be copied into the dnl.php file)
- the dnl.php file (to use as href into your download links)
- the files2dnl.txt (which contains the downloadable files and what logs to do)
- the dnl_log.txt (if logs have to be writen in a logfile)
- the dnlexept.txt (holding the forbidden strings in the user-agent : robots, webcrawlers

Website structure

files of    |    index.php      // header("location: /index.php"); // Nothing to see
the website |    files2dnl.txt  // list of downloadable files
            |    dnlexcept.txt  // blacklist for robots
dnl.php     |
(to use in  |    .. other downloadable files...
links for   +--lib
downloads)  |    class.dnl.php  // the download class
            |    ...other lib files...
            |    dnl_log.txt    // used if you log downloads into file
            |    ...other log files...

0) /     : It's the root directory of your website
1) /dnl  : It's the directory where your downloadable files are located
2) /lib  : It's the directory of your libraries  (such as classes)
3) /logs : It's the directry of your special logfiles

It's the class itself. This file can be located into your /lib directory.
You can include it in the dnl.php file with require() or you can copy
the code of the class in it instead of require(). 

If you want to log into a databases, using PDO, you can use several types :

- Informix
- ODBC et DB2
- PostgreSQL
- SQLite

You have to modify the members of this class with your own parameters (mail,
database --type, host, port, name, user, password--, logfile, etc... Once
you have changed your information, you no longer have to touch it.
Put it in the /lib directory.

The dnl.php file can be stored with the other files of your web site,
i.e. in the root diretory of it.
You have to use this file in your links as below :

- Download <a href="dnl.php?f=3">this file</a>.
- Download <a href="dnl.php?f=eccbc87e4b5ce2fe28308fd9f2a7baf3">this file</a>.

The content of dnl.php is short :

$num = $_GET["f"];
require("lib/class.dnl.php"); // instead of require(), you can copy here the content of class.dnl.php
if($num) { $file = new dnl($num); }

files2dnl.txt is a textfile which is read and exploited by the class.dnl.php
This file can be generated by mkfile2dnl.php (either in a web browser of in a
terminal). You just have to write the first and the last ID you want before use
as well as the default action (type of log).
Format of each line :

Examples :
12;c20ad4d76fe97759aa27a0c99bff6710;3;Zipped Gedcom File;

where :

- field 1: num (ex: 12)
  is a sequential number (1, 2, 3, ...) used as the ID of the file to download

- field 2: md5(num) (ex: c20ad4d76fe97759aa27a0c99bff6710)
  It's the md5 of num. [here, md5(12)]. It's another ID of the file to download
  It's possible to use either num or md5(num) as ID of the file to download.
  If somebody downloads several files (file 1, file 2, etc.) using the ID num :
  dnl.php?f=1, dnl.php?f=2, etc., maybe he can tries to download all your files
  using the other numbers (dnl.php?f=3 ... dnl.php?f=97, etc.)
  If you use md5(num) as ID, he don't knows if the ID is a random string or
  a md5(number) or a md5(string filename) and it's really more difficult for an
  Internet user to try to download all your files.
  So, as for me, I prefer to use md5(num)

- field 3: action (ex: 3)
  the field action (as a number) can be :
  . 0 : no action (no special log) when a download occurs
  . 1 : log it to a file
  . 2 : log it with a mail
  . 4 : log it to a database
  it's possible to combine several actions. examples:
  . 3 (file + mail)
  . 7 (file + mail + database)
  In all cases the file located on your web server will be logged in your http
  server logs, even if no action (action=0) is specified in the files2dnl.txt

- field 4: subject (ex: Zipped Gedcom File)
  This field is only used if you want log the download with a mail sent to you.
  It indicates the subject of the mail, subject preceded by the member $subject ("[DNL]")
  Not used when no action or log into a file or a database. So, if you log without
  mail, this field can be empty or with a 0 value.

- field 5: filename|url (ex: |
  a) filename : It's the filename of the file to be downloaded from your website
     and from the download directory. If you write only the filename, the file
     sent will be the file stored into (or the directory
     specified in the class.dnl.php, $dnldir member)
     If the file proposed to be downloaded is located in another place in your
     website, you have to indicate the complete url of that file such as :
     in this case (in that initial version) your file will be considered as an external
     file to your web server ; so, it will be sent but the size will not be reported.
     Maybe corrected in the next version of that class.
  b) url : It's the filename with its complete URL on the Internet. So, you can
     propose to download files which are stored on others hosts and log these downloads
     (file, mail, database --without their size--) but not into your http server logs.

Robots and webcrawlers search the web and collect all the links to reference them.
We can see it in the log files of web servers the user-agents recorded such as :
- Mozilla/5.0 (compatible; AhrefsBot/6.1; +
- Mozilla/5.0 (compatible; SemrushBot/6~bl; +
- Mozilla/5.0 (compatible; DotBot/1.1;,
- Mozilla/5.0 (compatible; Seekport Crawler;
The dnlexcept.txt file will be in the directory of files to download ($dnldir = ./dnl)
and will contain the characteristic character strings that can be identified in these
user-agents such as :
A visitor user-agent containing these character strings will end the download and the file will
neither be sent nor logged. You can update this file if new robot characteristic strings are found.
The strings in this file can be written in upper or lowercase.

Where to log

1) file : dnl_log.txt :
jj/mm/aaaa hh:mn:ss;ip-number;file-ID;size;downloaded-file;user-agent

2) Mail :
Specify your mail address in the class.dnl.php, $to and $headers members

3) database : Table site_Downloads v0.1 :
CREATE TABLE site_Downloads (
  `datime` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Date-time of the download',
  `ip` VARCHAR(20) NOT NULL DEFAULT '' COMMENT 'Download from that IP',
  `idf` INTEGER NOT NULL DEFAULT 0 COMMENT 'ID (num) of the downloaded file',
  `bytes` INTEGER NOT NULL DEFAULT 0 COMMENT 'Size of the downloaded file',
  `fname` VARCHAR(250) NOT NULL DEFAULT '' COMMENT 'File downloaded: file or URL',
  `ua` VARCHAR(128) NOT NULL DEFAULT '' COMMENT 'File downloaded with that user-agent',
  PRIMARY KEY(`idd`)
) ENGINE=MyISAM COMMENT='Downloads table';

NB: If you change the table name, change the $table member in the class.dnl.php

If you have some other questions, feel free to mail me at or
tweet me at @fr_phpuser

07/05/2020. Pierre Fauque

  Files folder image Files  
File Role Description
Accessible without login Plain text file dnl.php Example uses into downloads links
Plain text file class.dnl.php Class Download class v0.3
Accessible without login Plain text file files2dnl.txt Data List of downloadable files
Accessible without login Plain text file dnlexcept.txt Data Blacklist for webcrawlers and robots (by signature or IP)
Accessible without login Plain text file mkfiles2dnl.php Aux. Make the downloadable files
Accessible without login Plain text file doc.dnl.txt Doc. Documentation v0.2
Accessible without login Plain text file README.txt Data Infos about Class and author

 Version Control Unique User Downloads Download Rankings  
This week:0
All time:7,497
This week:277Up

For more information send a message to info at phpclasses dot org.