8722 sujets

Développement web côté serveur, CMS

Bonjour à tous,

Je viens de passer l'après midi à tester les multiples solutions que j'ai trouvé pour faire apparaitre la fenêtre d'enregistrement du fichier sur un lien.

Je développe actuellement un site internet pour mon label de musique. On a décider de proposer en téléchargement des fichiers mp3 de certains de nos artistes. Cependant, un lien <a href"etc...> classique lance automatiquement le player (Windows Media Player ou Quicktime, selon PC ou Mac).
On souhaite que la fenêtre "enregistrer sous..." apparaisse automatiquement.

J'ai essayé énormément de solutions en PHP (avec les headers, etc...) mais aucune ne fonctionne correctement (au mieux, j'ai réussi à avoir des fichiers mp3 qui faisaient 1 ko). Auriez vous par hazard sous la main un script qui marche ? (java ou PHP).

Merci beaucoup pour votre aide.

Pour info, un lien vers une page d'exemple : http://www.bonustracksrecords.com/artist.php?ID=1
Modifié par volonia75 (10 Mar 2008 - 20:32)
Salut Smiley cligne

Avec ceci :


$file= 'monfichier.mp3';

$taille=filesize($file);

header('Content-Type: application/force-download; name="'.$file.'"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.$taille);
header('Content-Disposition: attachment; filename="'.$file.'"');
header('Expires: 0');
header('Cache-Control: no-cache, must-revalidate');
header('Pragma: no-cache');
readfile($file);

exit(); 
Enfin, pour rendre dynamique par exemple :

Tu fais un lien vers le fichier (manage_dl.php) qui contient ce code :

list($fichier, $extension) = explode("-", $_GET['fichier']);

$file= $fichier.'.'.$extension;

$taille=filesize($file);

header('Content-Type: application/force-download; name="'.$file.'"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.$taille);
header('Content-Disposition: attachment; filename="'.$file.'"');
header('Expires: 0');
header('Cache-Control: no-cache, must-revalidate');
header('Pragma: no-cache');

readfile($file);

exit(); 


Ce fichier se trouve à la racine de ton dossier, ainsi que les fichiers à envoyer.

Tu appelle le fichier que tu viens de créer comme ceci :

manage_dl.php?fichier=monsong_a_telecharger-mp3


Le lien est créer comme ceci :

- manage_dl.php <= nom du fichier
- ?fichier= <= variable que l'on va transmettre
- monsong_a_telecharger <= nom du fichier sans extension, attention, ne pas avoir de "-" (tiret) dans le nom, sinon le script coince.
- - <= permet la démarquation entre le nom du fichier et son extension
- mp3 <= extension du fichier à télécharger.

Normalement, en cliquant sur ce lien, l'utilisateur aura la fenêtre pour ouvrir/sauvegarder directement.

Pas besoin de faire une quelconque target="_blank", juste en cliquant sur le lien, le fichier sera proposé en téléchargement Smiley cligne
Modifié par Super_baloo8 (10 Mar 2008 - 20:55)
Merci Super_Baloo8,

T'es génial, ça marche au poil sous FF et IE...je teste ça demain sur un mac.

Tu viens de résoudre un problème que j'ai tenté de résoudre en plusieurs heures...Il est pourtant très proche de ceux que j'ai essayé dans l'après midi...mais bon, ça marche HOURRA !



Smiley biggrin
Je t'en prie Smiley cligne

Un petit bonus qui te sera peut être utile, compter le nombre de téléchargement Smiley cligne

Tu peux le faire par Mysql (mais lourd les accès à chaque fois), ou par écriture dans un fichier.

Je reprend le premier fichier d'origine :



list($fichier, $extension) = explode("-", $_GET['fichier']);

$file= $fichier.'.'.$extension;

$monfichier = fopen($file.'.txt', 'r+');

$visites = fgets($monfichier);
$visites++;

fseek($monfichier, 0);
fputs($monfichier, $visites);
fclose($monfichier);

$taille=filesize($file);

header('Content-Type: application/force-download; name="'.$file.'"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.$taille);
header('Content-Disposition: attachment; filename="'.$file.'"');
header('Expires: 0');
header('Cache-Control: no-cache, must-revalidate');
header('Pragma: no-cache');

readfile($file);

exit(); 


Après, pour le compteur fonctionne, il faut que tu est crée le fichier txt qui porte le même nom que ton fichier que tu télécharge, mais avec en plus de l'extension normale de ton fichier, le .txt

Après, pour récupérer les infos, t'as plus qu'a lire le contenu du fichier.

$monfichier = fopen('lenom_du_fichier.mp3.txt', 'r+');
$nbr_dl_lenom_du_fichier_mp3 = fgets($monfichier);
fclose($monfichier);

echo $nbr_dl_lenom_du_fichier_mp3;


Comme ça tu peux te faires des stats pour savoir quels chansons sont les plus dl Smiley cligne
Modifié par Super_baloo8 (10 Mar 2008 - 22:57)
Bonjour,

2 petites précisions:

Côté sécurité, il faut filtrer les variables entrantes:

// éviter une variable vide
if(empty($_GET['fichier']) {
  exit('Nom fichier manquant.');
}
// éviter les caractères suivants dans le nom de fichier: / \ : * ? " < > |
// NB: si on autorise un chemin alors retirer le / mais empêcher ../ avec str_replace()
if(!preg_match('`^[^/\\:*?"<>|]*$`', $fichier)) {
  exit('Nom fichier incorrect.');
}
// s'assurer que le fichier existe
if(!file_exists($fichier)) {
  exit('Fichier inexistant.');
}


Ensuite pour la lecture du fichier, readfile() peut poser problème en fonction de la mémoire allouée à php (si le fichier est plus gros que la ram disponible). Si jamais ça se présente utiliser la fonction suivante (qui lit le fichier par tranche):

readbigfile($file) {
		// bytes per chunk, using 3mb
		$chunksize = 3*1024*1024;

		// open the file in binary mode
		if(($handle = fopen($file, 'rb')) === false) {
			return false;
		}
		// read it
		else do {
			if(($chunk = fread($handle, $chunksize)) === false)
				return false;	// an error occured
			// display
			echo $chunk;
			// free memory
			unset($chunk);
		} while(feof($handle) === false);

		// close the file
		if(fclose($handle) === true)  {
			return true;
		}
		else {
			return false;
		}
}

Modifié par Necromantik (11 Mar 2008 - 11:40)
Administrateur
Sinon, il y a la méthode toute simple du .htaccess

<Files *.mp3>
ForceType applicaton/octet-stream
Header set Content-Disposition attachment
</Files>
Vive Dew \o/

à la condition d'être sous apache c'est effectivement la plus simple et la plus économique des solutions.