Le chargement multiple en PHP
La fonction File_get_contents
Afin de charger des pages, la fonction file_get_contents est la plus souvent utilisée. Son avantage est d’être simple, elle ne demande aucune ouverture de flux, permet une récupération directe des données en format texte et tout aussi bien fonctionnel sur un flux distant que local.
Un exemple de code avec file_get_contents
$text_page1=file_get_contents("http://www.unsite.net/unepage.html"); $text_fichier=file_get_contents("/unchemin/unfichier.ext"); $text_ftp=file_get_contents("ftp://nom:passe@unsiteftp/unchemin/unfichier");
Chargement multiple
La problématique
Cependant, l’utilisation de file_get_contents montre sa limite dès que l’on cherche à charger plus de 3 ou 4 fichiers. En effet, le chargement de fichiers doit être réalisé suivant un mode file réalisant chaque chargement l’un après l’autre. Les chargement de fichier distant étant réalisé sur des temps calculable en dixième de secondes, le chargement pourra facilement atteindre la seconde dès 3 à 5 fichiers et la minute à partir de 50 fichiers.
Plusieurs difficultés majeures se présentent donc :
- un utilisateur n’attendrait pas un résultat devant son navigateur si longtemps
- la plupart des serveur php public, présente un temps d’execution limité pour chaque script php autour de 45 secondes
- le temps d’exécution est environ proportionnel au nombre de fichier
La solution multicurl
Curl est un gestionnaire de session distante. La librairie licurl créée par Daniel Stenberg est créé pour se connecter à différents services comme telnet, http, ftp ou nombre d’autres protocole. l’avantage dans notre cas est qu’elle permet de lancer plusieurs processus en parallèle et en tache de fond. Le désavantage est que cet ensemble nécessite une mise en place plus complexe.
Un exemple de code avec curl
/*** Initialisation des connections */ $urls=array("http://google.com", "http://voila.fr", "http://altavista.com", "http://kartoo.com"); $i=0; $multiCurl= curl_multi_init(); foreach($urls as $url){ $curls[$i] = curl_init(); curl_setopt($curls[$i], CURLOPT_URL, $url); curl_setopt($curls[$i], CURLOPT_HEADER, 0); curl_setopt($curls[$i], CURLOPT_RETURNTRANSFER, true); curl_multi_add_handle($multiCurl,$curls[$i]); $i+=1; } /*** Exécute le gestionnaire de connexion */ $running=null; do { curl_multi_exec($multiCurl,$running); } while ($running > 0); for($j=0; $j<$i; $j++){ $page[]=curl_multi_getcontent($curls[$j]); curl_multi_remove_handle($multiCurl, $curls[$j]); } /*** Ferme les gestionnaires */ curl_multi_close($multiCurl);
La solution popen
Une dernière solution est l’utilisation de popen. Son grand avantage et tout à la fois son inconvénient majeur est la possibilité d’utiliser cette fonction pour toutes les commandes du système accessible à l’interpréteur php. En effet, nombre de serveur ne laisse accessible que peu de fonctions. D’autre part, la mise en place est relativement archaïque et ressemble à l’ouverture fermeture de fichier présente en C.
Un exemple de code avec popen
$urls=array("http://google.com"; "http://voila.fr"; "http://altavista.com"; "http://kartoo.com"); # Lancement des traitement en parallèle foreach($urls as url){ $f[]=popen("wget ".$url); } # Lecture des résultats for($i=0; $i<count($urls); $i++){ $str = fgets($f[$i]); fclose($f[$i]); }