I'm using the following code for users to download files from my website. It works fine for files under 50MB, but fails immediately for larger files. Can someone explain why this is happening and how to fix it? Some of the downloadable files are over 800MB, so I need this working.

Thanks in advance

<?php
 error_reporting(E_ALL);
 ini_set('display_errors', '1');

$php_scripts = '../../php/';
require $php_scripts . 'PDO_Connection_Select.php';
require $php_scripts . 'GetUserIpAddr.php';

$ip = GetUserIpAddr();
if (!$pdo = PDOConnect("foxclone_data"))
{   echo "unable to connect";
   exit;
}

function mydloader($l_filename=NULL){    
    if( isset( $l_filename ) ) {
        $filename = $mysqli->real_escape_string($l_filename));

        $ext = pathinfo($filename, PATHINFO_EXTENSION);
        if  ($ext == '.deb')
            header('Content-Type: octet-stream');
        elseif ($ext == '.iso')
            header('Content-Type: application/x-cd-image');
        elseif ($ext =='.gz')
            header('Content-Type: application/zip');
        else
            header('Content-Type: octet-stream');

            header('Content-Description: File Transfer');
            header("Content-Disposition: attachment; filename={$filename}");
            header('Pragma: public');
            header('Expires: 0');    
            header('Cache-Control: must-revalidate');
            header('Pragma: public');
            header('Content-Length: ' . filesize($filename));   
            readfile($filename);


        // Get lookup id
        $test = $pdo->query("SELECT lookup.id FROM lookup WHERE inet_aton('$ip') >= lookup.ipstart AND inet_aton('$ip') <= lookup.ipend");
        $ref = $test->fetchColumn();
        $ref = intval($ref);

        // Insert record in download table
        $stmt = $pdo->prepare("INSERT INTO download (`address`, `filename`, `ip_address`, `lookup_id`) VALUES (?, ?, inet_aton('$ip'),?)");
        $stmt->execute([$ip, $ext, $ref]) ; 
      }

    else {
        echo "isset failed";
        }  
}      
mydloader($_GET["f"]);

Dani AI

Generated

— this usually comes down to PHP or webserver limits and how the file is streamed. is right to point you at runtime settings, and is pointing you toward streaming/readfile issues. Below are focused checks and a safe streaming pattern you can try.

First, quick checklist: increase or remove execution time limits and let the script continue if the client disconnects (see set_time_limit and ignore_user_abort); turn off PHP output buffering and zlib compression; validate the requested path with realpath() / is_file() and confirm filesystem permissions; inspect PHP-FPM/Apache/Nginx error logs for termination or memory messages. When using PHP to send big files, stream in chunks rather than loading the whole file into memory — use fopen/fread and flush to push data out (fopen, fread, flush).

A better production approach is to let the webserver deliver the file and have PHP only authorize the request: use X-Sendfile (Apache) or X-Accel-Redirect (Nginx) so the webserver handles the heavy I/O (see mod_xsendfile and X-Accel-Redirect (nginx)). Post relevant error-log lines if you want help interpreting them.

Recommended Answers

All 2 Replies

php.ini has a maximum file size limit, maximum execution time, maximum memory, etc. You most likely are hitting one of these limits.

commented: and even if not one of those, limits set in the web server configuration or the configuration of some proxy or firewall that guards that server +0
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.