Forcer téléchargement d'un gros contenu en "streaming"

Eléphant du PHP | 291 Messages

17 nov. 2008, 17:01

Bonjour,

Je ne sais pas si ma question est réellement avancée ou non, je vous laisse seuls juges...

Voilà mon utilisateur peut exporter les résultats de sa dernière requete sous forme de fichier CSV.
Pour cela, j'exécute la requete associée, et je construit tout le contenu CSV au sein d'une variable,
puis je force le téléchargement de ce contenu via les headers.

Seulement voilà, lorsque cette variable dépasse une certaine taille, on atterit sur une page blanche. J'imagine que c'est le strlen() ou le md5() qui posent quelques soucis sur une variable de ce genre.

Quels sont les pistes que vous me conseillerez ? Y a-t-il un moyen de faire télécharger ce contenu en "flux" ?

ViPHP
ViPHP | 4674 Messages

17 nov. 2008, 19:01

Hey :),

À quelle taille arrives-tu ?
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Eléphant du PHP | 291 Messages

18 nov. 2008, 10:38

Je dirais une vingtaine de Mo ...

ViPHP
ViPHP | 4674 Messages

18 nov. 2008, 19:31

Et si tu ouvres un tampon, que tu écris au pas à pas dedans, et que tu envoies le tampon à la fin, ça te donne quoi ? Ce serait plus intelligent et moins coûteux en mémoire je pense.

Voir la gestion des tampons dans PHP.
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Eléphant du PHP | 291 Messages

19 nov. 2008, 17:08

L'idée est bonne, j'avais déjà testé (donc c'est forcément bon !!), mais le comportement n'est toujours pas le bon...

Au lieu d'obtenir une page blanche après 3 secondes, le serveur travaille pendant une petite minute, puis m'affiche la page blanche...

:x

ViPHP
ViPHP | 4674 Messages

19 nov. 2008, 19:17

C'est possible de voir du code ou pas ?
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Eléphant du PHP | 291 Messages

20 nov. 2008, 16:55

Oui bien sûr...

        ob_start();
        $content = "";
        foreach ($users as $user)
        {
                $content .= $user;
                $content .= PHP_EOL;
        }

        define('CFG_SEND_FILENAME', 'export-users.txt');
        define('CFG_FILESIZE',      strlen($content));
        define('CFG_FILE_MD5',      md5($content));
        define('CFG_DATE_FORMAT',   'D, d M Y H:i:s');

        error_reporting(0);
        ini_set('zlib.output_compression', 0);

        header('Pragma: public');
        header('Last-Modified: '.gmdate(CFG_DATE_FORMAT).' GMT');
        header('Cache-Control: must-revalidate, pre-check=0, post-check=0, max-age=0');
        header('Content-Tranfer-Encoding: none');
        header('Content-Length: '.CFG_FILESIZE);
        header('Content-MD5: '.base64_encode(CFG_FILE_MD5));
        header('Content-type: plain/text');
        header('Content-Disposition: attachment; filename="'.CFG_SEND_FILENAME.'"');
        header('Date: '.gmdate(CFG_DATE_FORMAT, time()).' GMT');
        header('Expires: '.gmdate(CFG_DATE_FORMAT, time()+1).' GMT');
        header('Last-Modified: '.gmdate(CFG_DATE_FORMAT, time()).' GMT');

        echo $content;
        ob_end_flush();

ViPHP
ViPHP | 4674 Messages

20 nov. 2008, 17:00

Et si tu fais quelque chose du genre (qui correspondrait plus à ma première idée) :
error_reporting(0); 
        ob_start();

        ini_set('zlib.output_compression', 0); 

        define('CFG_SEND_FILENAME', 'export-users.txt'); 
        define('CFG_FILESIZE',      strlen($content)); 
        define('CFG_FILE_MD5',      md5($content)); 
        define('CFG_DATE_FORMAT',   'D, d M Y H:i:s'); 

        header('Pragma: public'); 
        header('Last-Modified: '.gmdate(CFG_DATE_FORMAT).' GMT'); 
        header('Cache-Control: must-revalidate, pre-check=0, post-check=0, max-age=0'); 
        header('Content-Tranfer-Encoding: none'); 
        header('Content-Length: '.CFG_FILESIZE); 
        header('Content-MD5: '.base64_encode(CFG_FILE_MD5)); 
        header('Content-type: plain/text'); 
        header('Content-Disposition: attachment; filename="'.CFG_SEND_FILENAME.'"'); 
        header('Date: '.gmdate(CFG_DATE_FORMAT, time()).' GMT'); 
        header('Expires: '.gmdate(CFG_DATE_FORMAT, time()+1).' GMT'); 
        header('Last-Modified: '.gmdate(CFG_DATE_FORMAT, time()).' GMT'); 

        foreach ($users as $user)
                echo $user . PHP_EOL;
 
        ob_end_flush();
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Eléphant du PHP | 291 Messages

21 nov. 2008, 18:19

Une page blanche, pure, vierge de tout code, propre, lavée avec mir laine spécial buffer. :(

ViPHP
ViPHP | 4674 Messages

23 nov. 2008, 21:42

Et si tu envoies autre chose sur la sortie ? Si tu n'envoies pas une en-tête de téléchargement ?
D'ailleurs, essaye des autres en-têtes, car utiliser un fichier (vide) et écrire un autre contenu me paraît étrange :?.
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Eléphant du PHP | 291 Messages

28 nov. 2008, 12:30

Bon en choissant d'afficher mes resultats 1000 par 1000, ça passe, mais par contre, ça met bien un temps relativement important pour retourner plusieurs dizaines de milliers d'utilisateurs....

Je retourne donc au titre du topic, quelqu'un connait-il les entetes qui vont bien pour un transfert de données sous forme de flux ?