[info] [php] Forcer un téléchargement

marsien

Grand Maître
Il est parfois intéressant ou nécessaire de forcer le téléchargement d'un fichier. Rien d'indélicat ou de sournois dans le principe. :merci:

Un ex. qui devrait parler à Johann & Pirlouit : il est parfois préférable de pouvoir télécharger un document pdf plutôt que de le voir s'ouvrir dans son navigateur. C'est intéressant quand le pdf est de grosse taille, que la lecture du contenu n'est pas nécessaire dans l'immédiat, etc. Dans le cas qui m'intéressait aujourd'hui, le but était de laisser le choix au visiteur entre voir ou télécharger des pdf, et ce sans devoir utiliser le fastidieux menu contextuel (clic droit) pour les néophytes.

Quelques rapides recherches m'ont dirigé vers un code basé sur l'envoi de header http. Ce code permet d'afficher la fenêtre de téléchargement des navigateurs ; il peut ressembler à ceci :
Code:
$fichier = 'monfichier';
$chemin = 'telechargement/' . $fichier;
if (file_exists($chemin))
{
	header('Content-disposition: attachment; filename="' . $fichier . '"');
	header('Content-Type: application/force-download');
	header('Content-Transfer-Encoding: binary');
	header('Content-Length: '. filesize($chemin));
	header('Pragma: no-cache');
	header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
	header('Expires: 0');
	readfile($chemin);
}
else
{
	$erreurFichier = 'le fichier "' . $fichier . '" n\'existe pas. Veuillez-nous excusez pour le désagrément.';
}
On retrouve un code similaire à celui-ci un peu partout sur le Web. Il marche bien, pas de souci... du moins tant qu'on se contente de vraiment enregistrer le fichier cible.

Seulement voilà, les navigateurs proposent aussi d'ouvrir le fichier à télécharger (c'est les choix "ouvrir" du menu de téléchargement). Dans ce cas, le code marche toujours, sauf pour IE (comme par hasard diront les mauvaises langues ;) ). Dans le cas d'un pdf par exemple, IE récupère bien le fichier, ouvre bien Adobe Reader, mais pas de bol, Reader affiche un message d'erreur comme quoi le fichier pdf n'existe pas :/

Il est en fait assez simple de remédier au problème, puisqu'il ne s'agissait que d'un Cache-control trop restrictif pour IE. Il faut supprimer les option "no-cache" et "no-store". On obtient au final ce code qui marche même pour l'option "ouvrir" de d'Internet Explorer :
Code:
$fichier = 'monfichier';
$chemin = 'telechargement/' . $fichier;
if (file_exists($chemin))
{
	header('Content-disposition: attachment; filename="' . $fichier . '"');
	header('Content-Type: application/force-download');
	header('Content-Transfer-Encoding: binary');
	header('Content-Length: '. filesize($chemin));
	header('Pragma: no-cache');
	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
	header('Expires: 0');
	readfile($chemin);
}
else
{
	$erreurFichier = 'le fichier "' . $fichier . '" n\'existe pas. Veuillez-nous excusez pour le désagrément.';
}
En espérant que ça puisse servir à quelques uns :)
 

Dom83

Habitué
Je ne comprend pas comment utiliser ce code dans une page où il y a plusieurs fichiers à télécharger. Eclairez-moi s'il vous plait.

Comme je l'explique dans un , j'aimerai que les musiques de ma page se téléchargent au lieu de se lire lorsque mes visiteurs cliquent dessus.
 

daveledave

Nouveau membre
Salut,

Ce script est top pour faire du force-download de fichiers locaux qu'on a sur son serveur.

Le pb c'est que j'essaye de faire du force-download à partir d'une page de mon site, mais qui téléchargerait une page sur un site qui n'est pas à moi (le fichier est énorme et je ne veut pas le mettre sur mon serveur).

Or qd je remplace :
readfile(fichier local );
par
readfile(http://cheminversfichierdistant);

ca ne marche pas. Quelqu'un peut m'aider ?

Merci !!

A+

David
 

batchy

Grand Maître
simple : c'est une mauvaise idée.

c'est une mauvaise idée du point de vue technique car le traffic va passer du serveur distant à ton serveur puis au client. si l'autre serveur est pas sur le même réseau alors la lenteur du téléchargement risque d'augmenter et tu va gaspiller de la bande passante. et de plus tu pourrai faire un effort et ne pas linker à l'arrache les fichiers d'un autre site ;) ...

le mieux c'est de faire ça sur l'autre serveur.
 

alieneur

Nouveau membre
Merci aussi, ca m'a permis de corriger un problème sous IE6 (encore lui !) quand on faisait "ouvrir".

Tout le reste marchait bien : "Enregistrer" sous IE6 et "Ouvrir" ou "Enregistrer" sous Firefox.

J'attends de voir si ca marche bien sous Mac, et aussi sur les versions de IE plus récente (7 et 8)

 

lawebmachine

Nouveau membre
Bonjour

Ca ne fonctionne pas chez moi , ça me met ce message

Parse error: syntax error, unexpected T_VARIABLE in /home3/dbcnewsc/public_html/foued/espace pro/telecharger.php on line 13


Qui peut m'aider ?

Merci Beaucoup

La webmachine de
 

zeb

Modérateur
:pfff: On s'en cogne de savoir le nom du fichier et son chemin complet.
Par contre, nous donner le contenu du fichier aux alentours de la ligne 13, c'eut été un peu plus intelligent.
 

lawebmachine

Nouveau membre
Bonjour

J'ai juste copier la totalité du message d'erreur ... tout le monde ne sait pas qu'il n'est pas utile de procéder comme ça... de plus je ne maîtrise absolument pas le PHP ....

Enfin si j'ai mis le lien du site , c'est juste pour permettre de voir où ça pêche ... l'idée de "pub" n'est pas présente dans mon esprit sur des forum de PHP ect ... pour ça j'ai d'autres moyens.

Ca c'est pour la réponse que je trouve quelque peu "agressive"

enfin pour répondre à ta question je n'ai pas copié le code car il est dans le message de "marsien" mais je veux bien le recopier si ça peut t'éviter de lire son message entier

Code :

1.$fichier = 'monfichier';
2.$chemin = 'telechargement/' . $fichier;
3.if (file_exists($chemin))
4.{
5. header('Content-disposition: attachment; filename="' . $fichier . '"');
6. header('Content-Type: application/force-download');
7. header('Content-Transfer-Encoding: binary');
8. header('Content-Length: '. filesize($chemin));
9. header('Pragma: no-cache');
10. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
11. header('Expires: 0');
12. readfile($chemin);
13.}
14.else
15.{
16. $erreurFichier = 'le fichier "' . $fichier . '" n\'existe pas. Veuillez-nous excusez pour le désagrément.';
17.}
 

zeb

Modérateur
Bonjour,

Ce que tu prends pour de l'agressivité n'est que le reflet de ma lassitude par rapport à des gens qui s'imaginent qu'on peut user et abuser de la bonne volonté des membres des forum sans faire soi-même un petit effort. De plus, lire le règlement du forum par exemple, et le respecter est la politesse minimum sur un forum. En le lisant, tu y apprendras que le code se publie ici sous certaines conditions de mise en forme.

---------------------------------------

La ligne 13 de ton extrait de code ne contient pas de variable, je doute qu'il y ait correspondance exacte entre ton fichier et cet extrait. Il faudrait nous dire à quelle ligne de cet extrait correspond l'erreur PHP.

Bon, il est possible aussi que tu ais une bête faute de frappe à la ligne 12 (13-1). Vérifie bien ton code.

(Utilise la fonction Edition pour virer le saimal.fr de ton message. N'en profite pas pour y remettre de la "pub"; N'hésite pas à mettre un lien vers ton site dans ta signature ;) )
 
G

Guest

Invité


salut marsien ton code est le bien venu pour nous qui debutons en programmation et qui avions besoin de document mais le probleme c'est ou entrer ce code pour l'ouverture du fichier. de plus si tu a des document en ta possession concernat la programation web que ce soit java ajax c sharp et bien d'otre...


EDIT MODERATION : Pas de coordonnées privées en public ! C'est pas le PMU du coin ici ! :o
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 079
Messages
6 716 709
Membres
1 586 247
Dernier membre
MrAzgarIII
Partager cette page
Haut