PHP: Stellen Sie eine Datei zum Download bereit, ohne den direkten Link anzugeben

12

Ich möchte Rechnungen zum Download bereitstellen. Derzeit verwende ich ein einfaches Nummerierungsschema (Rechnung-01.pdf, Rechnung-02.pdf usw.). Ich weiß, dass ich stattdessen Hashes verwenden könnte, um die Daten zu verschleiern.

Ist es auch möglich, PHP zu verwenden und die Rechnungen zu bedienen, indem der Benutzer nicht direkt darauf verweist?

Frank Vilea
quelle
Ja. Wie wäre es mit " rechnungs.invalid / ... "?
Mailq

Antworten:

26

Es gibt sogar ein Beispiel dafür auf 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');
?> 

Oder erweitern Sie das ein bisschen mit

<?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");
}
?>
Verschmieren
quelle
5

Sam hat die Antwort. Legen Sie sie auch in einem Verzeichnis mit .htaccess ab:

Authname Private
AuthType basic
require user noadmittance

Das verhindert direkten Zugriff, wenn sie die URL kennen. Sie können es weiterhin mit readfile () aus Ihrem PHP-Skript lesen.

Charlie
quelle
1
Aufgrund Ihres Vorschlags hatte ich gerade eine andere Idee: Ich habe alle Rechnungen außerhalb des WWW-Ordners abgelegt. :-) Danke noch einmal!
Frank Vilea
1
Ja noch besser!
Charlie
3

Ich fand für diese ausgezeichnete Anleitung: Wie man große Dateien über PHP bedient .

Besonders nützlich ist der lighttpd-Trick - Wenn Ihr PHP zufällig unter lighhtpd ausgeführt wird, muss das Skript nur den "X-Sendfile" -Header setzen, und lighttpd liest und sendet die Datei für Sie (und es weiß genau, wie man Dateien sendet).

AKTUALISIEREN:

Lighttpd hat diese Funktion und es gibt eine mod_xsendfile für Apache2.

(Zitiert aus der NginX-Dokumentation )

Sandman4
quelle
0

Meine Funktion mit automatischer MIME-Typerkennung:

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);
}

Verwendungszweck :

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

Achten Sie darauf, mit PHP nichts anderes zu senden (kein Echo).

Samuel Dauzon
quelle