Instantly share code, notes, and snippets.

Embed
What would you like to do?
PHP file downloader
<?php
# Prepare php.ini settings - adjust these values if needed
ini_set('upload_max_filesize', '128M');
ini_set('max_input_time', '300');
ini_set('memory_limit', '128M');
ini_set('max_execution_time', '300');
ini_set('post_max_size', '128M');
try {
# Clear buffers
if (ob_get_level()) {
while (ob_get_level()) {
ob_end_clean();
}
}
# Get file
$file = isset($_GET['f']) ? $_GET['f'] : false;
# You can setup a chunk size to read the file in pieces instead of the whole content all at
# the same time. This is recommended if you want to use a download speed limit (see next option)
$chunksize = 8 * 1024;
# You can limit the downloading by setting up a value to sleep between reading chunks
# Pass the value as microseconds
# Examples:
# 1000000 1 second
# 2000000 2 seconds
# 500000 0.5 seconds
# 100000 0.1 seconds
$limit = false;
# Check for existing file
if ($file) {
# Set path to search in and read files from
$path = '/path/to/download/folder';
# Validate passed file
$file = preg_replace('/\.\.\/|[^a-z0-9\.\-\_]|^\.+|\.+?$/i', '', $file);
$file = trim($file);
# Check if file exists, is a valid file and is also readable
if (file_exists($file) && is_file($file) && is_readable($file)) {
# Set file size
$fs = filesize($file);
# Headers
header('Content-Description: File Transfer');
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename="' . $file . '"');
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: ' . $fs);
# fopen and fread in chunks (the "b" flag is for binary mode - best choice so far)
$handle = fopen($file, "rb");
$buffer = '';
while (!feof($handle)) {
$buffer = fread($handle, $chunksize);
echo $buffer;
# If a limit is set, sleep the process for the specified duration in microseconds
if ($limit) {
usleep((int)$limit);
}
}
fclose($handle);
} else {
throw new \Exception("404 - not found");
}
} else {
throw new \Exception("forbidden");
}
} catch (\Exception $e) {
header('Content-Type: application/json');
echo json_encode(['error' => $e->getMessage()], JSON_FORCE_OBJECT);
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment