Précédent   Forum des professionnels en informatique > PHP > Langage > Fonctions
Fonctions Forum d'entraide sur les fonctions PHP. Avant de poster -> FAQ fonctions et Sources diverses
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 24/03/2011, 17h34   #1
Invité de passage
 
Inscription : avril 2010
Messages : 35
Détails du profil
Informations forums :
Inscription : avril 2010
Messages : 35
Points : 4
Points : 4
Par défaut Variable globale tronquée à l'extérieur de la fonction

Bonjour,

Tout d'abord je tiens a m'excuser pour l'absence d'accents dans mon texte, je vous ecris depuis un clavier qwerty. Je suis actuellement en stage aux USA et je suis confronte a un probleme que je n'arrive pas a resoudre depuis ce matin.

Je dois lire tous les fichiers XML d'un dossier et ecrire leur contenu dans une base MySQL. Tout est ok, j'ai presque fini a vrai dire.
Il ne me reste qu'un probleme : certaines valeurs (chaines) sont tronquees, c'est a dire que la partie de la chaine se trouvant juste avant une apostrophe est supprimee.

J'utilise la fonction xml_set_character_data_handler($XMLparser, "functionText"); ou functionText est la fonction appellee en callback (voir mon code ci-dessous).
Qui dit callback dit (je suppose ?) pas de variable retournee, donc je suis oblige d'utiliser des variables globales. Et a cause du switch, je ne peux pas effectuer mon traitement SQL directement dans ma fonction appellee en callback. Bref, je dois faire passer mes variables a l'exterieur de la fonction.
Sauf que j'ai ce probleme de variable tronquee avant une quote.
Quand j'echo ma variable dans la fonction, c'est ok. Par exemple :
Citation:
Chef Paul Prudhomme’s Magic Seasoning Blends Inc.
Mais a l'exterieur ca donne :
Citation:
’s Magic Seasoning Blends Inc.
Je suppose que le Äôs est du a l'encodage... je ne sais pas si ça peut jouer.

J'ajoute que les fichiers XML sont generes dynamiquement par un AppleScript qui les exporte depuis Adobe InDesign. Mais quand on les ouvre avec un fichier texte tout est ok niveau encodage.
A terme, les donnees sont enregistrees dans le BDD en UTF-8.

Voici une partie de mon code :
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
 
//- XML Parser functions
 
    function functionOpenTag($parser, $tagName, $Attributes)
    {
        //Just keep the tag name to use it in functionText()
        global $lastTagRead;
        $lastTagRead = $tagName;
    }
 
    function functionCloseTag($parser, $tagName)
    {
        //Forget the last tag read
        global $lastTagRead;
        $lastTagRead = "";
    }
 
    function functionText($parser, $text)
    {
        global $lastTagRead;
        switch ($lastTagRead) {
            case "TITLE": $GLOBALS['subheading'] = mysql_real_escape_string($text); break;
            case "BODY": $GLOBALS['body'] = mysql_real_escape_string($text); break;
            case "NUMBER": $GLOBALS['adid'] = (int)$text; break;
            case "COMPANY": $GLOBALS['company_name'] = mysql_real_escape_string($text); echo $GLOBALS['company_name']; break;
            case "CONTACT": $GLOBALS['contact'] = mysql_real_escape_string($text); break;
            case "ADDRESS": $GLOBALS['address'] = mysql_real_escape_string($text); break;
            case "PHONE": $GLOBALS['phone'] = mysql_real_escape_string($text); break;
            case "FAX": $GLOBALS['fax'] = mysql_real_escape_string($text); break;
            case "EMAIL": $GLOBALS['email'] = mysql_real_escape_string($text); break;
            case "URL": $GLOBALS['url'] = mysql_real_escape_string($text); break;
            case "ADSIZE": $GLOBALS['adsize'] = mysql_real_escape_string($text); break;
            case "ADTYPE": $GLOBALS['adtype'] = mysql_real_escape_string($text); break;
            case "IMG1": $GLOBALS['pic1'] = mysql_real_escape_string($text); break;
            case "IMG2": $GLOBALS['pic2'] = mysql_real_escape_string($text); break;
            case "IMG3": $GLOBALS['pic3'] = mysql_real_escape_string($text); break;
        }
	     $image = $pic1;
	     if(!isset($image) || trim($image)=="") {
		  $image = $pic2;
		  if (!isset($pic2) || trim($pic2)=="")
		       $image = $pic3;
		       if (!isset($pic3) || trim($pic3)=="")
			    $image = $pic4;
				 if (!isset($pic4) || trim($pic4)=="")
				 $image = "";
	     }      
    }
 
//-----
 
/* This is the correct way to loop over the directory. */
	    while (false !== ($file = readdir($folder))) {
	        if (substr($file, strlen($file)-4, 4) == ".xml") { //get only the xml files
 
			    $XMLparser = xml_parser_create(); // Create XML parser
			    xml_set_element_handler($XMLparser, "functionOpenTag", "functionCloseTag"); // Call these functions when an Open or Close tag is found
			    xml_set_character_data_handler($XMLparser, "functionText"); // When text is found, we call functionText()
 
etc... (ensuite c'est l'ajout dans la bdd, mais le probleme survient avant)
Merci d'avance !
.Spirit est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/03/2011, 21h32   #2
Membre chevronné
 
Avatar de micetf
 
Homme Fred
Professeur des Ecoles
Inscription : mai 2009
Messages : 503
Détails du profil
Informations personnelles :
Nom : Homme Fred
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Professeur des Ecoles
Secteur : Enseignement

Informations forums :
Inscription : mai 2009
Messages : 503
Points : 701
Points : 701
Bonjour,

Est-ce que la réponse ne serait pas ?

Sinon,
plus généralement,
pourquoi ne pas encapsuler tes fonctions de rappel dans une classe,
les tags et les nœuds de texte devenant des attributs de cette classe.
(ainsi, plus besoin de variables globales).

En procédant de la sorte,
pour chaque fichier xml, tu créeras une instance de cette classe et
à l'aide de la fonction xml_set_object,
tu rendras le parser utilisable depuis cet objet (toutes les méthodes de rappel, affectées par xml_set_element_handler(), seront les méthodes de celui-ci).

Ce qui donnerait (à la louche) :
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php  
class recupXML
{
	private $lastTagRead=null;
	private $noeuds=array(
		'subheading'=>null,
		'body'=>null,
		'number'=>null
		);
 
	function functionOpenTag($parser, $tagName, $Attributes)
	{
		//Just keep the tag name to use it in functionText()
		$this->lastTagRead = $tagName;
	}
 
    function functionCloseTag($parser, $tagName)
    {
        //Forget the last tag read
        $this->lastTagRead = null;
    }
 
    function functionText($parser, $text)
    {
			switch ($this->lastTagRead) {
				case "TITLE": $this->noeuds['subheading'] .= mysql_real_escape_string($text); break;
				case "BODY": $this->noeuds['body'] .= mysql_real_escape_string($text); break;
				case "NUMBER": $this->noeuds['adid'] .= (int)$text; break;
			}
		}
		function getNoeuds() 
		{
			return $this->noeuds;
		}
}   
//-----
 
/* This is the correct way to loop over the directory. */
	while (false !== ($file = readdir($folder))) {
		if (substr($file, strlen($file)-4, 4) == ".xml") { //get only the xml files
			$XMLparser = xml_parser_create('UTF-8'); // Create XML parser
			$xml = new recupXML();
			xml_set_object($XMLparser,$xml);
			xml_set_element_handler($XMLparser, "functionOpenTag", "functionCloseTag"); // Call these functions when an Open or Close tag is found
			xml_set_character_data_handler($XMLparser, "functionText"); // When text is found, we call functionText()
			$f = file_get_contents($file);
			xml_parse($XMLparser,$f,TRUE);
			... les infos sont accessibles par la méthode $xml->getNoeuds();
		}
	}
 
}
Fred
micetf est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/03/2011, 16h50   #3
Invité de passage
 
Inscription : avril 2010
Messages : 35
Détails du profil
Informations forums :
Inscription : avril 2010
Messages : 35
Points : 4
Points : 4
Bonjour !

Je ne peux que te remercier.
Aujourd'hui j'ai accès à mon ordinateur donc je peux écrire avec les accents (c'est tellement mieux).

Hier après-midi en voyant ton post et ton lien vers une réponse possible, j'ai pensé que ce n'était pas ce que je recherchais, persuadé que ce que mon parseur XML tirait était correct.

J'ai donc appliqué la solution donnée dans la suite de ton post, j'ai tout passé en classes, avant de m'apercevoir du même problème. C'est en refaisant des test (echo des morceaux de textes tirés du XML) que j'ai compris que la chaîne était coupée en deux et que par conséquent ton lien menait vers ma solution.

Ce n'est pas un mal puisque c'est un peu plus propre avec cette classe.
Du coup, il faut en effet concaténer la chaîne et non pas l'affecter, car la méthode qui lit le texte peut être appelée plusieurs fois avec le même "lastTagRead".
Ce qui implique de ne pas initialiser les attributs de la classe à NULL mais à "" (chaîne vide).

Je te remercie énormément, le script est fonctionnel du coup.
D'un clic on lit un ensemble de fichiers InDesign et quelques secondes plus tard les infos sont dans la base. :p

Encore merci, bonne journée.
.Spirit est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/09/2011, 15h31   #4
Invité de passage
 
Inscription : mai 2009
Messages : 11
Détails du profil
Informations forums :
Inscription : mai 2009
Messages : 11
Points : 2
Points : 2
Juste un gros merci pour prendre la peine d'écrire aussi bien !!!!!
Et merci pour cette solution également.
longshot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/09/2011, 11h20   #5
Invité de passage
 
Inscription : avril 2010
Messages : 35
Détails du profil
Informations forums :
Inscription : avril 2010
Messages : 35
Points : 4
Points : 4
Pas de problème !

Bon courage.
.Spirit est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h01.


 
 
 
 
Partenaires

Hébergement Web