PHP: servir un fichier à télécharger sans fournir le lien direct

12

Je souhaite signifier les factures à télécharger. Actuellement, j'utilise un schéma de numérotation simple (facture-01.pdf, facture-02.pdf, etc.). Je sais que je pourrais utiliser des hachages à la place pour masquer les données.

Est-il également possible d'utiliser PHP et de servir les factures en ne demandant pas directement à l'utilisateur de les pointer?

Frank Vilea
la source
Oui. Que diriez-vous de " factures.invalide /… "?
mailq

Réponses:

26

Il y a même un exemple de cela sur 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');
?> 

Ou développez cela un peu avec

<?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");
}
?>
Tache
la source
5

Sam a la réponse. Mettez-les également dans un répertoire avec .htaccess:

Authname Private
AuthType basic
require user noadmittance

Cela empêchera l'accès direct s'ils connaissent l'URL. Vous pouvez toujours le lire à partir de votre script PHP avec readfile ().

Charlie
la source
1
En raison de votre suggestion, je viens d'avoir une autre idée: j'ai placé toutes les factures en dehors du dossier www. :-) Merci encore!
Frank Vilea
1
Ouais encore mieux!
Charlie
3

J'ai trouvé pour cet excellent guide: Comment servir de gros fichiers via PHP .

L'astuce lighttpd est particulièrement utile - Si votre PHP s'exécute sous lighhtpd, le script n'a besoin que de définir l'en-tête "X-Sendfile", et lighttpd lira et enverra le fichier pour vous (et il sait très bien comment envoyer des fichiers).

MISE À JOUR:

Lighttpd a cette fonctionnalité et il y a un mod_xsendfile pour Apache2.

( Extrait de la documentation NginX )

Sandman4
la source
0

Ma fonction avec détection automatique de type 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);
}

utilisation:

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

Faites attention à ne rien envoyer d'autre avec PHP (pas d'écho).

Samuel Dauzon
la source