Ecrit par
Jean-Francois Ortolo le mardi 22 juillet 2008 dans le thème :
PHP
Bonjour
Je fais du chargement de donn?es de sites externes par des fonctions
de socket telles que fsockopen, suivie de fputs ( pour la requ?te )
puis de fgets ( pour le header ), puis de fread pour les donn?es.
J'utilise les fonctions donn?es par un Am?ricain sur les commentaires
de la fonction fsockopen(), dans le PHP Manual.
En gros, voici le code:
$fp = fsockopen($host, 80, &$errno, &$errstr, 300);
// test sur $fp en cas d'erreur.
// pour fixer le timeout sur les donn?es
stream_set_timeout($fp, 3000);
// le header est en mode HTTP 1.1 obligatoire,
// le serveur n'accepte que cela.
$send = $contenu_de_l_header;
fputs($fp, $send);
unset($send);
$send = '';
do
{
$send .= fgets($fp, 4096);
}while( strpos($send, "\r\n\r\n") === false)
// Premi?re fonction de l'Am?ricain,
// pour d?tecter les contenus chunked,
// et permettre la d?compression si besoin
// lors de la lecture des donn?es.
$info=decode_header($send);
unset($send);
$send = '';
while(!feof($fp))
{
// il faut un fread pour interpr?ter le contenu
// brut en binaire.
$send .= fread($fp, 16384);
}
fclose($fp);
// Deuxi?me fonction de l'Am?ricain,
// elle interpr?te les contenus chunked ou compress?s,
// et les restitue suivant ce qu'indique le contenu
// de l'header.
$send = decode_body($info, $send);
// Enfin, on met le contenu
// dans une array.
unset($var);
$var = split("[\n]", $send);
// Et voila, le contenu de la page html
// est dans la variables indic?e, ligne par ligne.
// ***********************************************
Donc, voici mon probl?me:
Tout se passe comme si les donn?es dans certains cas ( al?atoires )
n'alimentaient pas correctement la variable $var, qui ne contient pas
la balise , d?tect?e par eregi("", $donnee)
Cependant, j'ai mis un timeout de 300 secondes ? l'ouverture du
socket ( d'ailleurs c'est s?r que le socket est ouvert, car le
traitement d'erreur ne d?tecte rien ), ce qui largement suffisant car le
param?tre $host est en r?alit? l'adresse ip en dur, qui est correcte.
De plus j'ai sp?cifi? un time out pour les donn?es de 3000 secondes,
soit 50 minutes, et d'ailleurs le timeout apparent r?el, est de l'ordre
de 3 ou 4 minutes.
Je lance ces chargements de mani?re r?p?titive pour diff?rentes pages
du m?me site, et ? peu pr?s une fois sur 7 ou 8 ( al?atoire ), la balise
n'est pas d?tect?e dans la variable indic?e $var[]
Je parcours la variables $var avec un indice de 0 ? (count($var) -
1), ce qui devrait ?tre correct.
Je fais subir ? chaque lignes rencontr?es, une conversion de
utf-8vers iso-8859-15 avec la fonction decode faite de cette mani?re:
function decode($var) {
$send = ereg_replace("\r$", "", $var);
$send1 = iconv("UTF-8",
"ISO-8859-15//TRANSLIT//IGNORE", $send);
$send2 = str_replace(chr(189), "oe", $send1);
$send3 = str_replace("\r", "", $send2);
return($send3);
}
Donc en gros, ? chaque lecture de ligne:
unset($donnee);
$donne = decode($var[$k]);
Donc, je fais:
$trouve = false;
for($i = 0; $i ", $donnee))
break;
// pour d?buter le traitement
if(eregi("", $donnee))
$trouve = true;
if($trouve)
{
// Traitement...
}
}
Le probl?me, c'est que dans certains cas, le traitement ne se fait
pas du tout.
Il ne devrait pas y avoir de probl?me, les donn?es sont des pages
html en utf-8, qui devraient bien ?tre traduites en iso par la fonction
decode(). D'ailleurs pour un autre site du m?me genre, ?? marche.
D'o? vient l'erreur ? ;)
Merci beaucoup de vos r?ponses.
Bien ? vous.
Amicalement.
Jean-Fran?ois Ortolo
Classé sous : send,
var,
donn,
fp,
decode