Normalmente, quando quiser permitir que um usuário baixe um arquivo, você simplesmente o coloca em um diretório sob a raiz do documento e deixa o Apache fazer o resto.
Deixe o PHP servir o download
No entanto, em alguns casos, isso não é bom o suficiente. Pode ser necessário fazer alguma autenticação primeiro ou você precisa pesquisar o nome do arquivo real. Nesse caso, você usaria PHP, o que resultaria em um script parecido com este:
authenticate(); # authenticate and authorize, redirect/exit if failed
$file = determine_file();
if (!file_exists($file)) trigger_error("File '$file' doesn't exist.", E_USER_ERROR);
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header("Content-Length: ". filesize($file));
readfile($file);
Isso significa que o PHP precisa ler o arquivo, que passa pelo buffer de saída, é descarregado no Apache e processado antes de enviar ao cliente. Se eu quiser fazer o armazenamento em cache com base no trabalho da última modificação, você precisa verificar o cabeçalho da solicitação if-modify-since, verificar o mtime do arquivo e enviar um cabeçalho 304 de resultado.
X-SendFile para o resgate
Não seria melhor dizer ao Apache, por favor, envie esse arquivo e pronto. Bem, você pode. Ao habilitar ‘mod_xsendfile’ no Apache, você pode enviar um X-SendFile
cabeçalho, que é processado pelo Apache.
authenticate(); # authenticate and authorize, redirect/exit if failed
$file = determine_file();
header("X-Sendfile: $file");
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
Observe que essa técnica foi copiada do Lighttp . NGinx oferece suporte a um cabeçalho alternativo denominado X-Accel-Redirect .