Search code examples
phpx-sendfile

X-Sendfile notification after finish download


I would need to set the download status to 0 when download has finished. I am using x-sendfile, but after finish download, dont set status.

My code:

header("X-Sendfile: $file");
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . $name . '"');

mysql_query("UPDATE `downloads` SET `download_status` = '1' WHERE `id` = '" . $last_down . "'");

Thanks for help


Solution

  • You can't detect when the client finished downloading the file if you using X-Sendfile. Simplest way is stream file by script.

    $handle = fopen($filepath, 'rb');
    if ($handle !== false) {
        @flock($handle, LOCK_SH);
    
        $size = filesize($filepath);
        $filename = basename($filepath);
        $old_max_execution_time = ini_get('max_execution_time');
        ini_set('max_execution_time', 0);
        $old_cache_limiter = session_cache_limiter();
        session_cache_limiter(false);
    
        if (ob_get_length()) ob_clean();
        header('Content-Type: application/octet-stream');
        header('Content-Transfer-Encoding: binary');
        header('Content-disposition: attachment; filename="'. $filename .'"');
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Accept-Ranges: bytes');
        header('Cache-control: private');
        header('Pragma: private');
        set_time_limit(0);
        while (! feof($handle) && (connection_status() === 0)) {
            if (! $buffer = @fread($handle, $interval)) {
                // Error
                exit;
            }
    
            print($buffer);
            flush();
        }
        @flock($handle, LOCK_UN);
        @fclose($handle);
        ini_set('max_execution_time', $old_max_execution_time);
        session_cache_limiter($old_cache_limiter);
    
        // ----------------------------------------------------
        // Downloading complete!
        // Here you can update your table row in DB...
        // ----------------------------------------------------
    
        exit;
    }