PHP: обслуживать файл для загрузки без предоставления прямой ссылки

12

Я хочу обслуживать счета для скачивания. В настоящее время я использую простую схему нумерации (invoice-01.pdf, invoice-02.pdf и т. Д.). Я знаю, что вместо этого я мог бы использовать хэши, чтобы скрыть данные.

Можно ли также использовать PHP и обслуживать счета, не предоставляя пользователю прямой доступ к ним?

Фрэнк Вилеа
источник
Да. Как насчет " invoices.invalid / ... "?
mailq

Ответы:

26

Есть даже пример этого на php.net

<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');

// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');

// The PDF source is in original.pdf
readfile('original.pdf');
?> 

Или расширить это немного с

<?php
if ( can_this_file_be_downloaded() ) {
  header('Content-type: application/pdf');
  header('Content-Disposition: attachment; filename="invoice.pdf"');
  readfile("{$_GET['filename']}.pdf");
} else {
  die("None shall pass");
}
?>
мазаться
источник
5

У Сэма есть ответ. Также поместите их в каталог с .htaccess:

Authname Private
AuthType basic
require user noadmittance

Это будет держать прямой доступ, если они знают URL. Вы все еще можете прочитать его из своего PHP-скрипта с помощью readfile ().

Чарли
источник
1
Из-за твоего предложения у меня просто появилась другая идея: я выставил все счета за пределы папки www. :-) Еще раз спасибо!
Фрэнк Вилея
1
Да еще лучше!
Чарли
3

Я нашел для этого превосходное руководство: как обслуживать большие файлы через PHP .

Особенно полезен трюк с lighttpd - если ваш PHP работает под управлением lighhtpd, скрипту нужно только установить заголовок «X-Sendfile», а lighttpd прочитает и отправит вам файл (и он хорошо знает, как отправлять файлы).

ОБНОВИТЬ:

Lighttpd имеет эту функцию и есть файл mod_xsend для Apache2.

(Цитируется по документации NginX )

Sandman4
источник
0

Моя функция с автоматическим определением типа MIME:

function serve_file($filepath, $new_filename=null) {
    $filename = basename($filepath);
    if (!$new_filename) {
        $new_filename = $filename;
    }
    $mime_type = mime_content_type($filepath);
    header('Content-type: '.$mime_type);
    header('Content-Disposition: attachment; filename="downloaded.pdf"');
    readfile($filepath);
}

Применение :

serve_file("/no_apache/invoice27342.pdf");

Обратите внимание, чтобы не отправлять что-либо еще с PHP (без эха).

Сэмюэл Даузон
источник