Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1790 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  [PHP]Envoyer une fichier à un utilisateur sans lui donner l'adresse

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[PHP]Envoyer une fichier à un utilisateur sans lui donner l'adresse

n°2051894
Matth002
Posté le 26-01-2011 à 08:56:13  profilanswer
 

Bonjour a tous.
 
Je tiens un site web dans lequel il y a une partie nécessitant un couple identifiant/mot de passe. Cet accès, je voudrais le faire payant; et il donnera droit à télécharger des fichiers (rien d'illégal, je précise tout de même). Donc, je voudrais pouvoir envoyer mes fichiers aux utilisateurs sans qu'ils puissent voir l'adresse; sinon il suffit que quelqu'un conaisse l'adresse du fichier et la donne a tout le monde.
 
Pour le moment, j'ai utilisé cela (inspiré de la phpdoc)
[php]  //Envoi du fichier
  ob_clean();
  flush();
  header('Content-Description: File Transfer');
  header('Content-Type: application/octet-stream');
  header('Content-Disposition: attachment; filename="' . $file . '"');
  header("Content-type: application/force-download" );
  header('Content-Transfer-Encoding: binary');
  header('Expires: 0');
  header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  header('Pragma: public');
  header('Content-Length: ' . filesize($path . '/' . $file));
  readfile($path . '/' . $file);
[/php]
 
Ca fonctionne, mais il faut du temps pour que le serveur commence à envoyer le fichier quand ce dernier est assez lourd (du genre 10mo). Qui plus est, l'utilisateur ne sait rien faire d'autre sur le site tant que le téléchargement n'est pas terminé; et enfin; ca ne fonctionne pas sous opera mini avec mon GSM.
J'avais pensé à copier le fichier dans un répertoire temporaire puis donner l'adresse, mais ça deviendra vite ingérable.
 
Avez vous d'autres idées? Merci d'avance.

mood
Publicité
Posté le 26-01-2011 à 08:56:13  profilanswer
 

n°2051900
rufo
Pas me confondre avec Lycos!
Posté le 26-01-2011 à 09:40:43  profilanswer
 

Apache est peut-être pas bien configuré non plus...


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
n°2051906
smaragdus
whores, drugs & J.S. Bach
Posté le 26-01-2011 à 10:14:19  profilanswer
 

Matth002 a écrit :


J'avais pensé à copier le fichier dans un répertoire temporaire puis donner l'adresse, mais ça deviendra vite ingérable.


 
Pourquoi ingérable ? C'est une solution qui est souvent employée et qui laisse la possibilité de reprendre le d/l si ça plante au milieu.
 
Avec un simple CRON qui efface les fichiers anciens (selon une durée que tu définis), c'est une solution qui vaut la tienne mais qui ne charge pas le serveur puisque c'est apache qui envoie les fichier sans passer par PHP.

n°2051919
esox_ch
Posté le 26-01-2011 à 10:36:26  profilanswer
 

+1
Y a pas 36'000 manières de s'y prendre ... soit tu passes direct par les sockets via readfile, soit tu lui poses ça dans un rep temporaire..
 
Le seul "hic" avec les rep temporaires c'est que si tu mets un cron trop court que le mec a une bande passante de merde, ça va planter. Au contraire, si tu mets un cron trop long tu risques que les liens commencent à se balader (ou de saturer ton HDD).


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
n°2051926
Matth002
Posté le 26-01-2011 à 10:45:37  profilanswer
 

Merci pour vos réponses.
 
Ce que je n'aime pas trop avec l'histoire de copier les fichiers, c'est que si le site devient populaire, le DD va passer son temps à gratter...
 
Est-ce qu'il y aurait moyen de "multithreader" le readfile? Je veux dire lancer une instance du script qui fait le readfile, mais permettre à l'utilisateur de continuer d'utiliser le site?
 
Et avec le readfile, pourquoi est-ce qu'il y a un délai avant qu'il commence a envoyer le fichier? UN délai de 1sec pour 10mo ne me dérange pas, mais là on est de l'ordre de la dizaine de seconde... Sans compter qu'il y a aussi un délai après la réception complete du fichier. Pourtant j'ai bien précisé la taille de ce dernier...
 
PS: Je vais quand même jeter un oeil du côté du CRON voir ce qui existe :) Merci pour le toyo

n°2051941
esox_ch
Posté le 26-01-2011 à 11:10:56  profilanswer
 

-Quand ton site sera populaire, tu pourras utiliser des solutions style memcached pour limiter les accès HDD.
- Ouvre la dans une nouvelle page (pas le choix)
- C'est le temps qu'il faut pour que apache load le tout probablement


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
n°2051992
Matth002
Posté le 26-01-2011 à 13:00:43  profilanswer
 

Je vais essayer de faire ca avec une nouvelle page, merci :)

n°2052425
Matth002
Posté le 27-01-2011 à 16:17:33  profilanswer
 

SAlut!
 
Je n'ai malheureusement pas réussi à résoudre mon problème avec le readfile et une nouvelle page: le site est toujours bloqué pendant le téléchargement. J'ai utilisé un autre script, donné en exemple dans la doc, mais rien a faire.
 

Code :
  1. //Ajout de l'information de download
  2.   $downloaded = $sql_file['downloaded'] + 1;
  3.   $sql_download -> sql_update(array('id' => $_GET['id_file']), array('downloaded' => $downloaded), $parameters['table']);
  4.   //Récupération du type
  5.   $mtime = ($mtime = filemtime($path . '/' . $file)) ? $mtime : gmtime();
  6.   $size = intval(sprintf("%u", filesize($path . '/' . $file)));
  7.   //Désactivation de la compression
  8.   @apache_setenv('no-gzip', 1);
  9.   @ini_set('zlib.output_compression', 0);
  10.   //Envoi des header
  11.   header("Content-type: application/force-download" );
  12.   header('Content-Type: application/octet-stream');
  13.   if (strstr($_SERVER["HTTP_USER_AGENT"], "MSIE" ) != false)
  14.    header("Content-Disposition: attachment; filename=" . urlencode(basename($path . '/' . $file)) . '; modification-date="' . date('r', $mtime) . '";');
  15.   else
  16.    header("Content-Disposition: attachment; filename=\"" . basename($path . '/' . $file) . '"; modification-date="' . date('r', $mtime) . '";');
  17.   header('Content-Length: ' . $size);
  18.   //Empecher les soucis avec de larges fichiers
  19.   set_time_limit(300);
  20.   // Cas de grands fichiers
  21.   $chunksize = 1 * (1024 * 1024); // how many bytes per chunk
  22.   if ($size > $chunksize) {
  23.     $handle = fopen($path . '/' . $file, 'rb');
  24.     $buffer = '';
  25.     while (!feof($handle)) {
  26.    $buffer = fread($handle, $chunksize);
  27.    echo $buffer;
  28.    ob_flush();
  29.    flush();
  30.     }
  31.     fclose($handle);
  32.   } else {
  33.     readfile($path . '/' . $file);
  34.   }
  35.   exit;
  36.  }


 
Une autre idée pour réussir à ne pas bloquer tout le site pendant le téléchargement? Un autre soucis est que une fois le téléchargement terminé, le navigateur continue de recevoir des données (dans chrome, le truc de téléchargement vert continue de tourner), alors qu'il a tout reçus... Sous firefox 4b10, même soucis. (il reste bloqué sur quelques secondes restantes pendant environ 15-20sec)

n°2052426
esox_ch
Posté le 27-01-2011 à 16:18:12  profilanswer
 

Mais qu'est-ce que tu entends par "bloquer tout le site" ?


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
n°2052444
Matth002
Posté le 27-01-2011 à 17:16:48  profilanswer
 

ben pendant le téléchargement, si j'essaye de retourner sur le site pour visiter une autre page, il ne se passe rien. Le brouteur charge la page (on voit l'animation), mais elle ne se charge effectivement qu'une fois le téléchargement terminé.
 
Par contre, deux utilisateurs différents peuvent heureusement vister le site sans avoir ce soucis si l'un des deux télécharge.
 
C'est comme si php refusait d'exécuter quoique ce soit d'autre tant qu'il n'a pas terminé le readfile pour chaque utilisateur.

mood
Publicité
Posté le 27-01-2011 à 17:16:48  profilanswer
 

n°2052461
rufo
Pas me confondre avec Lycos!
Posté le 27-01-2011 à 17:56:15  profilanswer
 

Si t'es sous Windows, c'est "normal", apache a beaucoup de mal à gérer les requêtes multiples. Sous Linux, devrait pas y avoir de pbs. Là, ton pb vient de la conf du serveur, je pense...


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
n°2052476
Matth002
Posté le 27-01-2011 à 18:55:38  profilanswer
 

Je suis sous linux. Pour la conf serveur, c'est pas vraiment moi qui m'en occupe, mais un amis. Il s'y connais assez en linux, mais n'a pas vraiment l'habitude des configurations de serveurs, de même que moi même. On essaye d'adapter comme on peut...
 
Ici, que faudrait-il modifier? ou du moins de quel côté dois-je chercher?

n°2052491
l0g4n
Expert en tout :o
Posté le 27-01-2011 à 21:26:09  profilanswer
 

Et sinon, un système de cache, mais avec des liens virtuels, pour ne pas multiplier les fichiers ? ( Attation, sa ne marche que pour un serveur linusk... )


---------------
Fort et motivé. Sauf parfois.
n°2052500
Matth002
Posté le 27-01-2011 à 21:57:58  profilanswer
 

Ca me parait compliqué tout ça...
 
Il doit quand même bien y avoir moyen de faire un readfile proprement non? C'est quand même la solution qui me semble la plus appropriée, efficace et simple d'implémentation...

n°2052509
l0g4n
Expert en tout :o
Posté le 27-01-2011 à 22:15:11  profilanswer
 

Bah faut que tout le fichier soit lu, et mis en ram par php avant d'être envoyé...
C'est pas ce que je trouve propre. Surtout que si tu veut faire télécharger un fichier > 10mo, faut changer les paramêtres de php. Si en face ya pas assez de BP, faut augmenter le temps max d'execution d'un script de manière démesurée...


---------------
Fort et motivé. Sauf parfois.
n°2052758
Matth002
Posté le 28-01-2011 à 17:19:05  profilanswer
 

Ce que je veux dire, c'est qu'il doit bien y avoir moyen simple de lire quelques bits du fichiers, l'envoyer par le socket, attendre accusé, et recommencer l'opération jusqu'a la fin... non? Un peu comme on ferais en java par exemple.

n°2052766
stealth35
Posté le 28-01-2011 à 17:36:12  profilanswer
 

pourquoi tu fais pas un lien unique en jouant avec la session ?

n°2054754
MEI
|DarthPingoo(tm)|
Posté le 07-02-2011 à 10:33:13  profilanswer
 

Matth002 a écrit :

Ce que je veux dire, c'est qu'il doit bien y avoir moyen simple de lire quelques bits du fichiers, l'envoyer par le socket, attendre accusé, et recommencer l'opération jusqu'a la fin... non? Un peu comme on ferais en java par exemple.


Oui on peut streamer en PHP...
 
Suffit de faire fopen('php://output') pour accéder a la sortie PHP via un stream, et de faire un steam_copy_to_stream du fichier à la sortie PHP.
( http://www.php.net/manual/fr/funct [...] stream.php )


---------------
| AMD Ryzen 7 7700X 8C/16T @ 4.5-5.4GHz - 64GB DDR5-6000 30-40-40 1T - AMD Radeon RX 7900 XTX 24GB @ 2680MHz/20Gbps |

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  [PHP]Envoyer une fichier à un utilisateur sans lui donner l'adresse

 

Sujets relatifs
Script PHP d'un éditeur de RPG[PHP] fournir un fichier hors document root
Problème d'affiche en PHP[PHP] arry_unique multidimentional + index d'array
[PHP] Méthode(s) pour mémoriser des variablesObtenir coordonnées GPS en fonction d'une adresse postale
Zip un fichier en code vba[Résolu] Configurer WampServeur pour accès au localhost
fichier binaire socket c 
Plus de sujets relatifs à : [PHP]Envoyer une fichier à un utilisateur sans lui donner l'adresse


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR