Normalement j'aime beaucoup me débrouiller tout seul pour résoudre mes problèmes, mais là je sèche complet.
Je vous explique :
Je dois importer dans une DB une grande quantité de données depuis différents fichiers XML distants (serveurs HTTP). Jusque là, pas de soucis. Comme 1 des fichiers est très volumineux (700Mo au moment ou je vous parle), j'ai codé mon parseur maison à l'aide de Sax.
Dans le principe, ça se passe comme ça : Le gros XML contient des références vers d'autres fichiers XML plus petits. Je parse donc le gros XML et pour chaque référence à un petit XML, je le télécharge et le parse à son tour pour extraire les infos. Le problème est ici : lorsque PHP va chercher un fichier distant, il créé un fichier temporaire dans lequel il copie le contenu du fichier distant. Mais quelle à été ma surprise, lorsque j'ai eu une erreur me disant "Too many opened files". Le problème vient du fait que PHP ne ferme pas ces fichiers temporaires (ou pas avant la fin du script plus exactement).
J'ai essayé de changer de technique, et d'utiliser cURL, sans succès, celui-ci fonctionnant exactement pareil.
Je vous met ici la portion de code consernée. Je ne met pas toute la classe du parseur, le fichier faisant presque 10Ko.
Code : Tout sélectionner
function __construct($xmlURL, $xmlGroupTagName, $xmlGroupTagGap, $useCurl = FALSE)
{
$this -> xmlURL = $xmlURL;
$this -> xmlGroupTagName = $xmlGroupTagName;
$this -> xmlGroupTagGap = $xmlGroupTagGap;
$this -> saxParser = xml_parser_create('UTF-8');
xml_set_object($this -> saxParser, $this);
xml_parser_set_option($this -> saxParser, XML_OPTION_CASE_FOLDING, FALSE);
xml_parser_set_option($this -> saxParser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
xml_set_character_data_handler($this -> saxParser, '__dataHandler');
xml_set_element_handler($this -> saxParser, '__startElement', '__endElement');
xml_set_default_handler($this -> saxParser, '__default');
if($useCurl)
{
$this -> xmlFileSocket = tmpfile();
$curlSession = curl_init($xmlURL);
curl_setopt($curlSession, CURLOPT_FILE, $this -> xmlFileSocket);
curl_setopt($curlSession, CURLOPT_ENCODING, 1);
curl_exec($curlSession);
if(curl_errno($curlSession))
{
echo 'On attend 5min';
sleep(300);
curl_exec($curlSession);
if(curl_errno($curlSession))
return FALSE;
}
curl_close($curlSession);
rewind($this -> xmlFileSocket);
}
Pour moi, le rêve serai de trouver un moyen de charger les fichiers XML directement dans un fichier temporaire que je créé moi (et donc que je peux fermer sur demande).
Je précise que le serveur http est un Apache 2 et que la version de PHP est la 5.4.4 le tout sur une Arch Linux :p à jour
J'espère vraiment qu'une âme charitable saura me dépatouiller de tout ça car je suis en train de cracker. Le reste du projet n'avance pas du coup, et je prend du retard.
Merci à tous ceux essairons