Précédent   Forum du club des développeurs et IT Pro > PHP > Langage
Langage Forum sur le langage PHP, la POO, les conventions, la sécurité, etc. Avant de poster : FAQ Langage, toutes les FAQ PHP, cours langage et sources PHP
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 09/01/2013, 10h40   #1
polemoss
Futur Membre du Club
 
Homme
Développeur Web
Inscription : décembre 2006
Messages : 61
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 30
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Activité : Développeur Web
Secteur : Communication - Médias

Informations forums :
Inscription : décembre 2006
Messages : 61
Points : 19
Points : 19
Par défaut XML DomDocument optimisation de code

Bonjour,

J'ai un fichier xml à traiter qui possède plus de 29000 noeuds, et j'ai besoin de votre aide pour optimiser mon code qui le parcours.

Pour le moment je peux traiter environ 14000 noeuds après quoi j'ai une erreur :
Citation:
Fatal error: Maximum execution time of 120 seconds exceeded....
Voici le code que je souhaite optimiser

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 
// recuperation du nombre d'enregistrement
$clients = $dom->getElementsByTagName("clients")->item(0);
if ($clients->hasAttribute("nb"))
{
	$nbClient = $clients->getAttribute("nb");
}
 
for($i=0; $i<$nbClient; $i++)
{
	$listClient = $dom->getElementsByTagName('client')->item($i);
	$arrSet = array();
	$arrSet['tstamp'] = $time;
	foreach($listClient->childNodes as $node)
	{
		if($node->nodeType == XML_ELEMENT_NODE)
                {
			$tagName = trim($node->tagName);
			$nodeValue = trim($node->nodeValue);
			if($tagName == 'datmod' or $tagName == 'datsup')
			{
				if(!empty($nodeValue)){
					list($date, $Heure) = explode('T', $nodeValue);
					list($annee, $mois, $jour) = explode('-', $date);
					list($heure, $minute, $seconde) = explode(':', $Heure);
 
					$nodeValue = mktime($heure, $minute, $seconde, $mois, $jour, $annee);
				}
				else{
					$nodeValue = 0;
				}
			}
			$arrSet[$tagName] = $nodeValue;
		}
	}
	$this->Database->prepare("INSERT INTO `tl_ds_preregistration` %s")->set($arrSet)->execute();
}

Pour info j'ai fait des tests en mettant en commentaire le foreach et l'insert into et j'ai le même problème, je pense donc qu'il faut que je lise mon XML autrement sans faire de boucle.

La ligne qui ne semble pas du tout être optimisé est celle ci :
Code :
$listClient = $dom->getElementsByTagName('client')->item($i);
Je vous joins un extrait du fichier XML
Fichiers attachés
Type de fichier : xml clients.xml (1,4 Ko, 1 affichages)
polemoss est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2013, 11h04   #2
Celira
Modératrice
 
Avatar de Celira
 
Femme
Développeuse PHP/Java
Inscription : avril 2007
Messages : 4 259
Détails du profil
Informations personnelles :
Sexe : Femme
Âge : 28
Localisation : France

Informations professionnelles :
Activité : Développeuse PHP/Java
Secteur : Industrie

Informations forums :
Inscription : avril 2007
Messages : 4 259
Points : 8 369
Points : 8 369
Le problème vient probablement du fait que $dom->getElementsByTagName('client') remonte tous les nodes <client>. Si tu as 29000 nodes <client>, ça fait un tableau de 29000 éléments à chaque tour de boucle... Tu peux commencer par sortir la lecture du xml de la boucle.
Code :
1
2
3
4
5
 
$nodesClients = $dom->getElementsByTagName('client');
for($i=0; $i<$nbClient; $i++)
{
    $listClient = $nodesClients->item($i);
__________________
Modératrice PHP
Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)

Pour afficher votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [CODEINLINE=php][/CODEINLINE]
Celira est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2013, 12h29   #3
polemoss
Futur Membre du Club
 
Homme
Développeur Web
Inscription : décembre 2006
Messages : 61
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 30
Localisation : France, Indre et Loire (Centre)

Informations professionnelles :
Activité : Développeur Web
Secteur : Communication - Médias

Informations forums :
Inscription : décembre 2006
Messages : 61
Points : 19
Points : 19
Bonjour,

Ça aurai pu en effet être une solution et je te remercie de m'avoir répondu.

Je suis du coup passé à simpleXML qui est bien plus rapide voici mon nouveau code :

Code php :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
$dom = new DomDocument();
$dom->load($this->folderXml . DIRECTORY_SEPARATOR . $this->fileUser);
 
if(!$dom->schemaValidate($this->folderXsd . DIRECTORY_SEPARATOR . $this->fileSchemaUser))
{
    $doNotContinue = true;
}
if(!$doNotContinue)
{
    $time = time();
    // Conversion élément DOM en SimpleXML => plus rapide
    $sxml = simplexml_import_dom($dom);
 
    // $sxml->results->clients['nb']; // Lecture attribut
 
    foreach ($sxml->xpath('//client') as $client) {
        $arrSet = array();
        $arrSet['tstamp'] = $time;
        $arrSet['code_cli'] = trim($client->code_cli);
        $arrSet['nom_cli'] = trim($client->nom_cli);
        $arrSet['codpos_cli'] = trim($client->codpos_cli);
        $arrSet['ville_cli'] = trim($client->ville_cli);
        $arrSet['code_site'] = trim($client->code_site);
        $arrSet['site'] = trim($client->site);
        $arrSet['datmod'] = $this->convertDateTime(trim($client->datmod));
        $arrSet['datsup'] = $this->convertDateTime(trim($client->datsup));
 
        $this->Database->prepare("INSERT INTO `tl_ds_preregistration` %s")->set($arrSet)->execute();
    }
    $this->log('L\'import utilisateur a été réalisé avec succès', 'dsAutomator importUser()', TL_CRON);
}

Avec ce code les 29000 noeuds sont traité en moins d'une seconde
polemoss est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 08h21.


 
 
 
 
Partenaires

Hébergement Web