Petite classe PHP pour forcer le Téléchargement

Voici une petite classe PHP bien pratique et issue de Ludik FrameWork.

Elle est simple et sans prétention, mais je croise souvent des internautes qui souhaitent ce genre d’outils sur le web. Alors, en attendant que le Ludik FrameWork soit disponible en téléchargement, je vous met à disposition cette classe.

Cette classe qui se nomme downloadFile va vous permettre de forcer le téléchargement d’éléments que vous souhaitez faire Downloader. En effet, il arrive parfois que vous souhaitiez proposer un pdf en téléchargement et ce dernier s’affiche directement dans le navigateur. Voici une classe qui vous sera utile :

<?php 
/** 
* @package Ludik_FrameWork_0.5 - Nacimiento 
* @author Franck Pertegas 
* @copyright LudiKreation 
* @link http://www.ludikreation.com 
* @license http://www.gnu.org/licenses/lgpl.html GNU General Lesser Public Licence, see LICENCE file 
* @divers Issu du développement pour des sites :: ludikreation de Franck Pertegas 
* @version 1.0.0 
* @Date 01/05/2009 
*/ 

/** * downloadFile 
* Classe de gestion de téléchargement - PHP 5 oblige - A utiliser dans une page vierge de toute sortie ! 
* @package Ludik_FrameWork 
*/ 
class downloadFile{ 
	
	/** 
	* nom du fichier a télécharger 
	* @var string 
	* @access public 
	*/ 
	public $filename; 
	
	/** 
	* nom du fichier pour la sauvegarde de l'internaute 
	* @var string 
	* @access public 
	*/ 
	public $newfilename; 
	
	/** 
	* chemin pour arriver au fichier 
	* @var string 
	* @access public 
	*/ 
	public $filepath; 
	
	/** 
	* taille du fichier 
	* @var string 
	* @access private 
	*/ 
	private $filesize; 
	
	/** 
	* encodage nécessaire pour le fichier 
	* @var string 
	* @access private 
	*/ 
	private $filemd5; 
	
	/** * Format de date de l'entete 
	* @var string 
	* @access public 
	*/ 
	public $dateformat; 
	/** 
	* Constructeur public 
	* @param string $filename :: le nom du fichier avec son extension bien sur^^ 
	* @param string $filepath :: le chemin du fichier, par défaut '' 
	* @param string $newfilename :: le nom du fichier pour l'internaute par default $filename 
	*/ 
	public function __construct($filename, $filepath = '', $newfilename = ''){ 
		
		$this->filename = $filename;<br ?--> $this->filepath = self::cleanPath($filepath);
		$this->dateformat = 'D, d M Y H:i:s';
		$this->filesize = filesize($this->filepath.$this->filename);
		$this->filemd5 = md5_file($this->filepath.$this->filename);

		if($newfilename == '')
		$this->newfilename = $this->filename;
		else
		$this->newfilename = $newfilename;

	}

	/**
	* Méthode public static (cleanPath([...])) permettant d'ajouter le slash au chemin si ce dernier n'y est pas
	* @param string $path :: le chemin entré
	*/
	public static function cleanPath($path){

		$path = $path;

		if(substr($path, -1, 1) != '/'){

			$path .= '/';

		}

		return $path;

	}

	/**
	* Méthode public static (getExtension()) permettant d'obtenir l'extension du fichier passé en argument (Une methode de la Classe uploadFile)
	* @param string $file :: le nom du fichier avec son extension bien sur^^
	* @return string l'extension (ex : "jpg")
	*/
	public static function getExtension($file){

		return substr($file, -3);

	}

	/**
	* Méthode public (forceDownload()) permettant de forcer un téléchargement de fichier - Renvoi plusieurs entete header !!
	* @return boolean si réussite (true) ou non (false).
	*/
	public function forceDownload(){

		//
		// Quelques éléments nécessaires
		//
		error_reporting(0);
		ini_set('zlib.output_compression', 0);

		/*
		* Les en tetes nécessaires
		*/

		//
		// Gestion du cache
		//
		header('Pragma: public');
		header('Last-Modified: '.gmdate($this->dateformat).' GMT');
		header('Cache-Control: must-revalidate, pre-check=0, post-check=0, max-age=0');

		//
		// Informations sur le contenu a envoyer
		//
		header('Content-Tranfer-Encoding: none');
		header('Content-Length: '.$this->filesize);
		header('Content-MD5: '.base64_encode($this->filemd5));
		header('Content-Type: application/octetstream; name="'.$this->filename.'"');
		header('Content-Disposition: attachment; filename="'.$this->newfilename.'.'.self::getExtension($this->filename).'"');

		//
		// Informations sur la réponse HTTP elle-meme
		//
		header('Date: '.gmdate($this->dateformat, time()).' GMT');
		header('Expires: '.gmdate($this->dateformat, time()+1).' GMT');
		header('Last-Modified: '.gmdate($this->dateformat, time()).' GMT');

		/*
		* Envoi du fichier
		*/

		if(readfile($this->filepath.$this->filename))
			return true;

	}

}

?>

Bien entendu cette classe est issue de diverses sources et recherches et permet donc de forcer le download de fichiers.

Comment l’utiliser ?

Tout d’abords n’oubliez pas que votre page qui utilisera cette classe devra être vierge de toute sortie, afin de ne pas faire planter le script.

<?php 
// Instanciation de l'objet (le fichier appelé, le chemin vers ce fichier, la nouvelle appellation du fichier lors du téléchargement) 
$download = new downloadFile('monfichier.pdf', 'mesfichiers/pdf', 'Mon-nouveau-nom-de-fichier'); // On force le download (return boolean) 
$download->forceDownload(); 
?>

 

Voilà, tout simplement et vous pouvez ainsi forcer le téléchargement et renommer le fichier ainsi téléchargé.

Pour toutes questions, remarques, contributions, n’hésitez pas…

Author: Franck Pertegas

Share This Post On

8 Comments

  1. Yo LudiKadmin,

    Effectivement je devait être un des nombreux internautes a chercher cette outil qui va me rendre je pense la vie un peu plus simple 🙂

    Il a fallut que je crame ma carte mére pour voir ton topic et découvrir se blog 😉

    Merci LudiKadmin continue comme ça=)

    Post a Reply
  2. Salut smelllike,

    Heureux que ça te plaise. En espérant que ça te serve 🙂

    Si tu as des améliorations ou ajouts, n’hésites pas je suis preneur.

    Bonne soirée

    Post a Reply
  3. Ha dommage je n’arrive pas à l’utiliser.

    j’ai mis la classe dans un fichier php externe et je fais un include(‘de la classe’)

    et je l’appel comme ceci
    forceDownload();
    }
    ?>

    ça déclanche quelque chose sauf que le résultat c’est décrire des carré bizare dans la page

    hum! peut être que je ne sais pas comment vraiment bien faire la chose

    salut

    Post a Reply
  4. Bonjour REM,

    Ça fonctionne même si ta classe est en include().

    Suis bien les instructions que je donne sur cet article.

    Il ne faut pas l’utiliser comme une fonction, mais bien comme une classe.

    A+

    Post a Reply
  5. ok, ça marche très bien.

    j’ai mis la classe et l’appel de la classe dans une page vide de tout contenu et voilà ça marche.

    par contre je fais exécuter la classe à partir d’un lien vers une page _blank. Le download se fait met on reste sur une page blanche vide.

    est-ce que tu aurais une idée pour plus de convivialité et ne pas se retrouvé sur une page blanche mais plutôt rester sur la page que je suis. Je suis capable de le faire mais je trouve ta classe super le fun et m’évite de toujours retaper dans l’entête le stock nécéssaire!

    merci beaucoup pour ton travail!

    voici l’adresse :
    http://aapq.org/aapq_evenement/dev/congres2013/inscription
    le lien est tout en haut de la page. télécharger le pdf

    Post a Reply
  6. Bonjour REM,

    oui, il suffit de ne pas mettre le lien avec target= »_blank »
    tu fais un lien normal et ça téléchargera le fichier sans te changer de page 🙂

    Post a Reply
  7. Effectivemnt! LudiKadmin

    maintenant c’est au poil!

    merci pour cette petite classe

    je crois qu’elle va suivre dans plein de projets différents

    salut

    Post a Reply
  8. Bonjour à tous, je voulais remercier LudiKadmin pour cette classe qu’il a créée mais j’ai une petite bug avec cette classe.
    Quand j’ai utilisé pour la première fois la classe ma machine a planté et j’ai du la forcer pour éteindre! et la deuxième fois ça s’est bien passée mais la troisième fois le problème que la première fois!!
    Je voulais vous demander pourquoi ça plante avant de mettre ça sur le serveur! Je travaille en local avec wampserver
    cordialement

    Post a Reply

Submit a Comment

Votre adresse e-mail ne sera pas publiée.