Назад | Перейти на главную страницу

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

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

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

Есть даже пример этого на 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");
}
?>

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

Authname Private
AuthType basic
require user noadmittance

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

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

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

ОБНОВИТЬ:

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

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

Моя функция с автоматическим определением типа 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 (без эха).