Return to Snippet

Revision: 64721
at September 12, 2013 05:33 by deanhouseholder


Initial Code
<?php

// Use PHP to serve files too big for Apache to deliver (>2GB)
function serveFile($file){
    if (file_exists($file)){
        $path_parts = pathinfo($file);
        $as = $path_parts['basename'];
        // Exec to determine correct file size (see's bigger files than PHP can see)
        $size = trim(`stat -c%s "$file"`);
        set_time_limit(0);

        header("Expires: Mon, 1 Jan 2010 01:00:00 GMT");
        header("Pragma: no-cache");
        header("Cache-Control: private");
        header("Content-Description: File Download");
        header("Content-Type: application/octet-stream");
        header("Content-Disposition: attachment; filename=\"".urlencode($as)."\"");
        header("Content-Length: $size");
        header("Content-Transfer-Encoding: binary");

        flush();
        $fp = popen("cat \"$file\" 2>&1", "r");
        while(!feof($fp))
        {
            // send the current file part to the browser
            print fread($fp, 1024);
            // flush the content to the browser
            flush();
        }
        fclose($fp);
    } else {
        header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
        print "File not found";
    }
}

$file = "../" . str_replace(array("/d/", "?f=","../"), "", trim(urldecode($_SERVER['REQUEST_URI'])));

// If the last character of the URL is & then trigger for Download
if (substr($_SERVER['REQUEST_URI'], -1) == "&"){
    $download = true;
    // Strip off & from the end of the $file variable
    $file = substr_replace($file, '', strlen($file)-1, 1);
}else{
    $download = false;
}

if (isset($_GET['f']) && $download == false){
    if (file_exists($file)){
        $size = number_format(trim(`stat -c%s "$file"`));
        $path_parts = pathinfo($file);
        $url_path = str_replace(array(" ","../"), array("%20",""), $file);
        print "Click to download <a href=\"/d/?f=".$url_path."&\">".$path_parts['basename']."</a>";
        print " (".$size." bytes)";
    } else {
        header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
        print "File not found";
    }
} else {
    serveFile($file);
}

?>

Initial URL


Initial Description
By default Apache won't allow you to download a file over 2GB.  This PHP script overcomes that along with some extra goodies.

The script will read from standard url path the file on the server to download and display the filesize along with a link to download it.

Setup:

1) Create a directory called "d" on the root of your website and name this script "index.php"

2) Create a .htaccess file with the following lines:

RewriteEngine On

RewriteBase /d/

RewriteCond %{REQUEST_DIRECTORY} !-d [NC]

RewriteRule ^(.*)$ index.php?f=$1 [L]

3) Craft a url in the format of: http://[website_url]/d/path/to/download/filename.dat

This will link to a file: http://[website_url]/path/to/download/filename.dat

If you want, you can also craft a url with a trailing "&" and it will automatically start downloading.

Example: http://[website_url]/path/to/download/filename.dat&

Initial Title
PHP Download script for any filesize

Initial Tags
php, download, apache

Initial Language
PHP