[RESOLU] Erreur téléchargement avec script de stéphane

jol5926jol5926 Member
juin 2018 modifié dans Entraide
[== Indéfini ==]
<?php
	# Emplacement des dossiers pour les compteurs de téléchargement et les fichiers à télécharger
	# (avec un / à la fin des chemins)
	
	$hits 		= dirname(__FILE__).'/data/medias/downloads/counter-hits/';
	$downloads 	= dirname(__FILE__).'/data/medias/downloads/';

	#==============================================
	
	/**
	 * Fonction qui comptabilise le nombre de téléchargements
	 *
	 * @param	filename	nom et emplacement du fichier des hits
	 **/
	function hitsCounter($filename) {
		$counter=0;
		if(@file_exists($filename)) {
			$f = @fopen($filename, "r");
			@flock($f, LOCK_EX); //lock the file
			$counter = intval(@fgets($f)); 
			@fclose($f);
		}
		$f = @fopen($filename, "w");
		@flock($f, LOCK_EX); //lock the file
		@fwrite($f, $counter+1);
		@fclose($f);
	}
	
	/**
	 * Protège une chaine contre un null byte
	 *
	 * @param	string chaine à nettoyer
	 * @return	string chaine nettoyée
	*/
	function nullbyteRemove($string) {
		return str_replace("\0", '', $string);
	}

	$h_file = null; # fichier compteur de téléchargement
	$d_file = null; # fichier à télécharger
	
	# Détermination des noms des fichiers
	if(isset($_GET['file']) AND !empty($_GET['file'])) {
		$filename = basename(nullbyteRemove($_GET['file']));
		$h_file = $hits.$filename.".txt";
		$d_file = $downloads.$filename;
	}

	# Contrôle de l'existence du fichier à télécharger
	if(!file_exists($d_file)) {
		die('File not found');
		exit;
	}
	
	# Mise à jour du compteur de téléchargement du fichier
	hitsCounter($h_file);
	
	# Envoi du fichier à l'utilisateur
	header('Content-Description: File Transfer');
	header('Content-Type: application/download');
	header('Content-Disposition: attachment; filename='.basename($d_file));
	header('Content-Transfer-Encoding: binary');
	header('Expires: 0');
	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
	header('Pragma: no-cache');
	header('Content-Length: '.filesize($d_file));
	readfile($d_file);
	exit;
	
?>


tuto :

il faut à la racine du site 
- un dossier : hits
- un dossier : downloads
mettre les fichiers à télécharger dans le dossier downloads
les compteurs sont stockés dans le dossier hits sous la forme monfichier.zip.txt
le script est à copier à la racine du site
apres faut adapter les chemins au debut du script si tu veux changer les emplacements
le script "download.php" est à appeler de cette façon:
download.php?file=monfichier.zip


Hello les amis,

Je viens de m'apercevoir que lorsque j'utilise le script ci-dessus, je n'arrive pas à télécharger un fichier qui fait 250 Mo.
Fait d'autres tests sur un pluxml vierge et avec un autre fichier de 250 Mo.
J'ai la même erreur, un message qui m'indique au bout de quelques secondes "perte connexion réseau".

J'ai fait un essai avec un lien direct et ça fonctionne !

Quelqu'un a une idée ?

Merci

Jol

Réponses

  • Hello,

    Je reviens vers vous concernant mon problème post #1.
    Je viens d'effectuer une série de test.
    Tous les téléchargement, en utilisant le script, fonctionne parfaitement si le fichier ne dépasse pas environ les 200 Mo, au-dessus, impossible de télécharger.

    Quelqu'un a une idée ??

    Si Stéphane est dans le coin, a-t-il une idée ?

    Merci
  • Un truc de ce style au debut du code ?
    [== Indéfini ==]
    ini_set('post_max_size', '400M');
    ini_set('upload_max_filesize', '400M');
    
  • jol5926jol5926 Member
    juin 2018 modifié
    je-evrard a écrit:
    Un truc de ce style au debut du code ?
    [== Indéfini ==]
    ini_set('post_max_size', '400M');
    ini_set('upload_max_filesize', '400M');
    

    Bonjour Jéjé,

    Content de te revoir parmi nous.
    :)
    Au début du code ?

    J'ai placé ce bout de code au début et toujours le même souci ?
  • StéphaneStéphane Member, Former PluXml Project Manager
    Bonjour

    L'instruction readfile() utilisée pour lire le fichier et le télécharger charge le fichier en mémoire avant de l'envoyer au client
    Dans le php.ini il y a une limite sur la taille maxi autorisée
    exemple
    memory_limit=32M
    

    tu peux donc augmenter cette valeur (si tu as la main sur ton php.ini), mais ça ne fera que déplacer le problème si tu as d'autres gros fichiers dont tu ne connais pas la taille à l'avance.

    l'autre solution est de découper en chunks le fichier

    rajoute la fonction suivante dans le code de ton programme
    <?php 
    function readfile_chunked ($filename) { 
      $chunksize = 1*(1024*1024); // how many bytes per chunk 
      $buffer = ''; 
      $handle = fopen($filename, 'rb'); 
      if ($handle === false) { 
        return false; 
      } 
      while (!feof($handle)) { 
        $buffer = fread($handle, $chunksize); 
        print $buffer; 
      } 
      return fclose($handle); 
    } 
    ?>
    

    et remplace
    readfile($d_file);
    

    par
    readfile_chunked($d_file);
    

    J'ai rien sous la main pour tester, donc je peux pas garantir que ça va fonctionner

    Consultant PluXml

    Ancien responsable du projet (2010 à 2018)

  • jol5926jol5926 Member
    juin 2018 modifié
    Stéphane a écrit:
    Bonjour
    l'autre solution est de découper en chunks le fichier

    rajoute la fonction suivante dans le code de ton programme
    <?php 
    function readfile_chunked ($filename) { 
      $chunksize = 1*(1024*1024); // how many bytes per chunk 
      $buffer = ''; 
      $handle = fopen($filename, 'rb'); 
      if ($handle === false) { 
        return false; 
      } 
      while (!feof($handle)) { 
        $buffer = fread($handle, $chunksize); 
        print $buffer; 
      } 
      return fclose($handle); 
    } 
    ?>
    

    et remplace
    readfile($d_file);
    

    par
    readfile_chunked($d_file);
    

    J'ai rien sous la main pour tester, donc je peux pas garantir que ça va fonctionner

    Merci Stéphane,
    ça fonctionne !
    :)
  • StéphaneStéphane Member, Former PluXml Project Manager
    @jol5926: :cool:

    Consultant PluXml

    Ancien responsable du projet (2010 à 2018)

Connectez-vous ou Inscrivez-vous pour répondre.