J'utilise actuellement des services Web SOAP externes qui permettent des téléchargements/uploads groupés de fichiers binaires (devraient permettre des fichiers plus volumineux). Je dois permettre à un utilisateur final de télécharger des fichiers via le navigateur avec une application PHP. Le traitement de petits fichiers fonctionne bien, mais les fichiers de plus de 25 Mo font que le serveur Web manque de mémoire. J'utilise le natif PHP Soap Client (pas de support MTOM), et demande le téléchargement en soumettant un formulaire. Actuellement, il semble que le serveur Web tente de télécharger l'ensemble du fichier avant d'envoyer quoi que ce soit au navigateur (par exemple, l'invite "Télécharger" n'apparaît qu'après que le fichier entier ait été traité via PHP).Diffusion de fichiers volumineux à partir d'un service Web externe via PHP
Ma méthode ressemble à quelque chose comme ça (désolé si c'est désordonné, j'ai été piratage à ce problème pendant un certain temps).
public function download()
{
$file_info_from_ws ... //Assume setup from $_REQUEST params
//Don't know if these are needed
gc_enable();
set_time_limit(0);
@apache_setenv('no-gzip', 1);
@ini_set('zlib.output_compression', 0);
//File Info
$filesize = $file_info_from_ws->get_filesize();
$fileid = $file_info_from_ws->get_id();
$filename = $file_info_from_ws->get_name();
$offset = 0;
$chunksize = (1024 * 1024);
//Clear any previous data
ob_clean();
ob_start();
//Output headers
header('Content-Type: application/octet-stream');
header('Content-Length: ' . $filesize);
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Accept-Ranges: bytes');
while($offset < $filesize)
{
$chunk = $this->dl_service()->download_chunked_file($fileid, $offset, $chunksize);
if($chunk)
{
//Immediately echo out the stream
$chunk->render();
$offset += $chunksize;
unset($chunk); //Shouldn't this trigger GC?
ob_flush();
}
}
ob_end_flush();
}
Ma question principale est: Quelle est la meilleure façon de sortie de gros morceaux binaires de ressources externes (Webservices, DB, etc.) par le biais de PHP à l'utilisateur final? De préférence sans tuer la mémoire/CPU trop.
Aussi je suis curieux de savoir ce qui suit:
Pourquoi pas le téléchargement rapide pop-up après la première sortie?
Pourquoi la mémoire n'est-elle pas libérée après chaque boucle dans la méthode about?
Vous pouvez également utiliser ob_implicit_flush au lieu d'appeler flush() à chaque fois. –