Forum Clubic

Erreur fonction php xml

Bonjour,

Je cherche à comprendre cette fonction :

function & parse(&$data){
$this->document = array();
$this->stack = array();
$this->parent = &$this->document;
return xml_parse($this->parser, $data, true) ? $this->document : NULL;
}

c’est surtout la derniere ligne, je ne trouve pas de documentation dessus, sur le ‘?’ et le ‘:’ !!!

Sachant qu’à cause d’elle j’ai l’erreur suivante :

Notice: Only variable references should be returned by reference in C:\Program Files\EasyPHP 3.0\www\testData\xml.php on line 73

Notice: Only variable references should be returned by reference in C:\Program Files\EasyPHP 3.0\www\testData\xml.php on line 73

Notice: Only variable references should be returned by reference in C:\Program Files\EasyPHP 3.0\www\testData\xml.php on line 73

Notice: Only variable references should be returned by reference in C:\Program Files\EasyPHP 3.0\www\testData\xml.php on line 73

si quelqu’un pourrait m’orienter svp

Il ne s’agit pas d’une erreur mais d’une Notice.

Le problème est que parse() doit retourner une référence or le return porte sur $this->document ou sur NULL. Dans le second cas, ce qui est demandé c’est donc de retourner une valeur, ce qui est contraire à la déclaration de la fonction (function & parse(&$data)), d’où la Notice.

Mets NULL dans une variable et retourne la.

merci pour ta réponse, j’ai fait :


function & parse(&$data){
		$this->document = array();
		$this->stack    = array();
		$this->null = NULL;
		$this->parent   = &$this->document;
		return xml_parse($this->parser, $data, true) ? $this->document : $this->null;

même erreur
j’ai tenté :

function & parse(&$data){
		$this->document = array();
		$this->stack    = array();
		$this->null = NULL;
		$this->parent   = &$this->document;
		return $null;

j’ai eu une nouvelle erreur :


Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

Warning: Variable passed to each() is not an array or object in C:\Program Files\EasyPHP 3.0\www\testData\newdata.php on line 151

la ligne 151 correspond au while de la fonction

function ExtraitItem($paArray, $psBlocName)
	{		
		while (list($sKey, $aValue) = each($paArray))
		{
			if (strtolower($sKey) == $psBlocName)
			{
				return $aValue;
			}
		}
		
		return null;
	}

et la fonction ExtraitItem() est utilisé dans la fonction:

function ChargeTableaux($pRequest, &$pasTitres, &$pasValeurs)
	{		
		$bFirst = true;
				
		// On utilise le premier fichier pour récupérer la liste des titres
		// Pour chaque établissement, on affiche les titres
		for($i=0; $i<mysql_num_rows($pRequest); $i++)
		{
			$sLicence = mysql_result($pRequest, $i,"cleident");
			$dayDate = date("l");
			// Lecture des données ([licence].xml)
			$sFileName = "upload/".$sLicence."/".$dayDate.".xml";
			if (file_exists($sFileName))
			{				
				$bAtLeastOne = true;
		
				// On charge le contenu du fichier	
				$sContent = file_get_contents($sFileName);
				$aData = XML_unserialize($sContent);
						
				// On extrait le bloc principal et les titres
				$aBloc = ExtraitItem($aData, "bloc");
				$aTitres = ExtraitItem($aBloc, "titres");
				$aValeurs = ExtraitItem($aBloc, "valeurs");
				
				if ($bFirst)
				{					
					// On récupère tous les titres et les stoque dans le tableau $pasTitres
					$j=1;
					$sTitre = ExtraitItem($aTitres, "titre".$j);
					while ($sTitre != null)
					{
						$pasTitres[] = $sTitre;
						$j++;
						$sTitre = ExtraitItem($aTitres, "titre".$j);
					}
					
					$bFirst = false;
				}
				
				// On récupère toutes les valeurs et les stoque dans le tableau $pasValeurs
				$j=1;
				$sValeur = ExtraitItem($aValeurs, "valeur".$j);
				while ($sValeur != null)
				{
					$pasValeurs[$j-1][] = str_replace(",", ".", $sValeur);
					$j++;
					$sValeur = ExtraitItem($aValeurs, "valeur".$j);
				}						
			}
			
		}

je ne connais pas trop ces fonctions parse, donc je ne sais pas trop m’en servir…je reprends juste un code déjà utilisé et développé par un développeur de l’entreprise dans laquelle j’effectue mon stage et où ce développeur n’y travaille plus maintenant.

Warning: Variable passed to each() is not an array or object : Pour comprendre, il faudrait que tu indique le contenu de $paArray.
Sinon, le code que tu as indiqué ne fait jamais appel à la fonction parse() : il doit donc en manquer…

Je te montre mes 3pages principales ou plutôt les pages qui me semblent utile pour voir d’où vient le probleme…

xmlparser.php


<?php

class XMLParser {
   var $filename;
   var $xml;
   var $data;
   
   function XMLParser($xml_file)
   {
       $this->filename = $xml_file;
       $this->xml = xml_parser_create();
       xml_set_object($this->xml, $this);
       xml_set_element_handler($this->xml, 'startHandler', 'endHandler');
       xml_set_character_data_handler($this->xml, 'dataHandler');
       $this->parse($xml_file);
   }
   
   function parse($xml_file)
   {
       if (!($fp = fopen($xml_file, 'r'))) {
             die('Cannot open XML data file: '.$xml_file);
               return false;
       }

       $bytes_to_parse = 512;

       while ($data = fread($fp, $bytes_to_parse)) {
           $parse = xml_parse($this->xml, $data, feof($fp));
           
           if (!$parse) {
               die(sprintf("XML error: %s at line %d",
                   xml_error_string(xml_get_error_code($this->xml)),
                       xml_get_current_line_number($this->xml)));
                       xml_parser_free($this->xml
                     );
           }
       }

       return true;
   }
   
   function startHandler($parser, $name, $attributes)
   {
       //$data['DATA'] = $name;
       if ($attributes) { $data['ATTR'] = $attributes; }
       $this->data[] = $data;
   }

   function dataHandler($parser, $data)
   {
       if ($data = trim($data)) {
           $index = count($this->data) - 1;
           // begin multi-line bug fix (use the .= operator)
           $this->data[$index]['VAL'] .= $data;
           // end multi-line bug fix
       }
   }

   function endHandler($parser, $name)
   {
       if (count($this->data) > 1) {
           $data = array_pop($this->data);
           $index = count($this->data) - 1;
           $this->data[$index]['CHILD'][] = $data;
       }
   }
}
?>

xml.php

###################################################################################
# XML_unserialize: takes raw XML as a parameter (a string)
# and returns an equivalent PHP data structure
###################################################################################
function & XML_unserialize(&$xml){
	$xml_parser = &new XML();
	$data = &$xml_parser->parse($xml);
	$xml_parser->destruct();
	return $data;
}
###################################################################################
# XML_serialize: serializes any PHP data structure into XML
# Takes one parameter: the data to serialize. Must be an array.
###################################################################################
function & XML_serialize(&$data, $level = 0, $prior_key = NULL){
	if($level == 0){ ob_start(); echo '<?xml version="1.0" ?>',"\n"; }
	while(list($key, $value) = each($data))
		if(!strpos($key, ' attr')) #if it's not an attribute
			#we don't treat attributes by themselves, so for an empty element
			# that has attributes you still need to set the element to NULL

			if(is_array($value) and array_key_exists(0, $value)){
				XML_serialize($value, $level, $key);
			}else{
				$tag = $prior_key ? $prior_key : $key;
				echo str_repeat("\t", $level),'<',$tag;
				if(array_key_exists("$key attr", $data)){ #if there's an attribute for this element
					while(list($attr_name, $attr_value) = each($data["$key attr"]))
						echo ' ',$attr_name,'="',htmlspecialchars($attr_value),'"';
					reset($data["$key attr"]);
				}

				if(is_null($value)) echo " />\n";
				elseif(!is_array($value)) echo '>',htmlspecialchars($value),"</$tag>\n";
				else echo ">\n",XML_serialize($value, $level+1),str_repeat("\t", $level),"</$tag>\n";
			}
	reset($data);
	if($level == 0){ $str = &ob_get_contents(); ob_end_clean(); return $str; }
}
###################################################################################
# XML class: utility class to be used with PHP's XML handling functions
###################################################################################
class XML{
	var $parser;   #a reference to the XML parser
	var $document; #the entire XML structure built up so far
	var $parent;   #a pointer to the current parent - the parent will be an array
	var $stack;    #a stack of the most recent parent at each nesting level
	var $last_opened_tag; #keeps track of the last tag opened.
	

	function XML(){
 		$this->parser = &xml_parser_create();
		xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
		xml_set_object($this->parser, $this);
		xml_set_element_handler($this->parser, 'open','close');
		xml_set_character_data_handler($this->parser, 'data');
	}
	function destruct(){ xml_parser_free($this->parser); }
	function & parse(&$data){
		$this->document = array();
		$this->stack    = array();
		$this->parent   = &$this->document;
		return xml_parse($this->parser, $data, true) ? $this->document : $null;
		
	}
	function open(&$parser, $tag, $attributes){
		$this->data = ''; #stores temporary cdata
		$this->last_opened_tag = $tag;
		if(is_array($this->parent) and array_key_exists($tag,$this->parent)){ #if you've seen this tag before
			if(is_array($this->parent[$tag]) and array_key_exists(0,$this->parent[$tag])){ #if the keys are numeric
				#this is the third or later instance of $tag we've come across
				$key = count_numeric_items($this->parent[$tag]);
			}else{
				#this is the second instance of $tag that we've seen. shift around
				if(array_key_exists("$tag attr",$this->parent)){
					$arr = array('0 attr'=>&$this->parent["$tag attr"], &$this->parent[$tag]);
					unset($this->parent["$tag attr"]);
				}else{
					$arr = array(&$this->parent[$tag]);
				}
				$this->parent[$tag] = &$arr;
				$key = 1;
			}
			$this->parent = &$this->parent[$tag];
		}else{
			$key = $tag;
		}
		if($attributes) $this->parent["$key attr"] = $attributes;
		$this->parent  = &$this->parent[$key];
		$this->stack[] = &$this->parent;
	}
	function data(&$parser, $data){
		if($this->last_opened_tag != NULL) #you don't need to store whitespace in between tags
			$this->data .= $data;
	}
	function close(&$parser, $tag){
		if($this->last_opened_tag == $tag){
			$this->parent = $this->data;
			$this->last_opened_tag = NULL;
		}
		array_pop($this->stack);
		if($this->stack) $this->parent = &$this->stack[count($this->stack)-1];
	}
}
function count_numeric_items(&$array){
	return is_array($array) ? count(array_filter(array_keys($array), 'is_numeric')) : 0;
}
?>

et newdata.php

<?PHP
	include('secure.php');	
	include('xmlparser.php');
	include('xml.php');
	no_cache();

	// CONNEXION MYSQL
	connexion();
	
	$id = $_GET["id"];
	
	echo "<span style='font-family : verdana; font-size : 12px;'>";
	if (!empty($gfullname))
		echo "Bonjour $gfullname";
	else
		echo "Bonjour $gpseudo";
		
	echo "</span>";	
	echo "<hr size=0><br>";
		
	// On recherche tous les établissements installés pour ce client
	$sRequete = "select * from licence where pseudo='".$gpseudo."'";
	$results=requete($sRequete);
	
	// Si aucune établissement n'est trouvé
	if(mysql_num_rows($results)==0)
	{		
		echo "<span style='font-family : verdana; font-size : 12px;'>";
		echo "Aucun établissement à afficher";		
		echo "</span>";
		echo "<br><br>";
		echo "<input type='button' onclick='javascript:document.location.reload();' value='Actualiser'>";						
	}
	else 
	{
		echo "</span>";
		echo "<span style='font-family : verdana; font-size : 25px;'>Votre tableau de bord d'aujourd'hui - Orchestra Web Manager</span>";		
		echo "<br><br>";
		echo '<table border="0" cellpadding="5" cellspacing="1" bgcolor="#999999"  style="font-family : verdana; font-size : 12px;">';
		echo '<tr valign="top"><td style="font-weight:bold;" bgcolor="#DDDDDD">Données de gestion</td>';		
		
		$nNbFichiers = 0;
		
		$aDay = array(1 =>"Lundi", 2 =>"Mardi", 3 =>"Mercredi", 4 =>"Jeudi", 5 =>"Vendredi", 6 =>"Samedi", 7 =>"Dimanche");	
		$dayDate = date("l");
		echo $dayDate;
		 
		// AFFICHAGE DE LA LIGNE TITRES
		for($i=0; $i<mysql_num_rows($results); $i++)
		{
		  $sLicence = mysql_result($results,$i,"cleident");
		  $sNom = mysql_result($results,$i,"nom");
		  
			// Lecture des données ([licence].xml)
			$sFileName = "upload/".$sLicence."/".$dayDate.".xml";
			
			if (file_exists($sFileName))
			{
				$sJour = $aDay[date("w", filemtime($sFileName))];
				
				// Ajoute la date et l'heure du fichier
			 	$sTime = $sJour.", ".date("d/m/Y H:i", filemtime($sFileName));
			 				 
		  	echo "<td align='right' bgcolor='#DDDDDD' style='padding :5px;' nowrap>";
		  	echo "<b>$sNom</b>";
		  	echo "<br>";
		  	echo "<span style='font-size : 10px;'>";
		  	echo $sTime;
		  	echo "</span>";
		  	echo "</td>";
		  	
		  	$nNbFichiers++;
			}
			
			
		}
		
		if ($nNbFichiers>1)
			echo "<td align='right' width='100' bgcolor='#DD3333' style='color: #FFFFFF; font-weight:bold; padding :5px;' nowrap>Totaux</td>";
		
		echo "</tr>";

		// MEMORISATION DES TITRES ET VALEURS
		$asTitres = array();
		$asValeurs = array();
		
		// On récupère les titres et les valeurs
		ChargeTableaux($results, $asTitres, $asValeurs);
		
		// Si aucun fichier n'a été trouvé
		if (empty($asTitres))
		{	
			echo "</table><br><br><span style='font-family : verdana; font-size : 12px;'>Aucunes données n'a été transmises pour le moment</span>";
			echo "<br><br>";
			echo "<input type='button' onclick='javascript:document.location.reload();' value='Actualiser'>";						
		}
		else
		{		
			// AFFICHAGE DE CHAQUE LIGNE
			$nTotalLignes = count($asTitres);				
			for ($j=0;$j<$nTotalLignes; $j++)
			{
				$sTitre = $asTitres[$j];
					
				if ($j%2>0)
					$sBGColor = "#F5F5F5";
				else
					$sBGColor = "#FFFFFF";
					
				echo "<tr><td bgcolor='$sBGColor' style='padding :5px;' nowrap>".$sTitre."</td>";
				
				$rTotal = 0;
				foreach($asValeurs[$j] as $rValue)
				{
					$rTotal += $rValue;
					
					echo "<td align='right' style='padding :5px;' bgcolor='$sBGColor'>".$rValue."</td>";				
				}
				
				if ($nNbFichiers > 1)
				{
					$sTotal = sprintf("%.02f", $rTotal);
									
					echo "<td align='right' style='padding :5px;' bgcolor='#FFCCCC'>".$sTotal."</td>";
				}
				
				echo "</tr>";
			}
			
			if ($nNbFichiers>1)
				$nCols = $nNbFichiers+2;
			else
				$nCols = $nNbFichiers+1;
			
			echo "<tr><td align='right' colspan=".($nCols)." bgcolor=#999999>";
			echo "<input type='button' onclick='javascript:document.location.reload();' value='Actualiser'>";				
			echo "</td></tr>";
			
			echo "</table>";
		}
	}
	echo "<br>";
	echo "<a style='font-family : verdana; font-size : 12px;' target='_blank' href=\"dateprecedente.php?login=1&id=".$id."&licence=".$sLicence."\">voir les dates précédentes</a>";
	echo "<br><br><hr size=0>";
	//double / à sup	
	//echo "[ <a style='font-family : verdana; font-size : 12px;' href=\"javascript:parent.location.href='http://www.orchestra-software.com'\">Se déconnecter</a> ]";
		echo "<a style='font-family : verdana; font-size : 12px;' href=\"login.php?login=1&id=".$id."\">Se déconnecter</a>";
	
	function ExtraitItem($paArray, $psBlocName)
	{		
		while (list($sKey, $aValue) = each($paArray))
		{
			if (strtolower($sKey) == $psBlocName)
			{
				return $aValue;
			}
		}
		
		return null;
	}
	
	function ChargeTableaux($pRequest, &$pasTitres, &$pasValeurs)
	{		
		$bFirst = true;
				
		// On utilise le premier fichier pour récupérer la liste des titres
		// Pour chaque établissement, on affiche les titres
		for($i=0; $i<mysql_num_rows($pRequest); $i++)
		{
			$sLicence = mysql_result($pRequest, $i,"cleident");
			$dayDate = date("l");
			// Lecture des données ([licence].xml)
			$sFileName = "upload/".$sLicence."/".$dayDate.".xml";
			if (file_exists($sFileName))
			{				
				$bAtLeastOne = true;
		
				// On charge le contenu du fichier	
				$sContent = file_get_contents($sFileName);
				$aData = XML_unserialize($sContent);
						
				// On extrait le bloc principal et les titres
				$aBloc = ExtraitItem($aData, "bloc");
				$aTitres = ExtraitItem($aBloc, "titres");
				$aValeurs = ExtraitItem($aBloc, "valeurs");
				
				if ($bFirst)
				{					
					// On récupère tous les titres et les stoque dans le tableau $pasTitres
					$j=1;
					$sTitre = ExtraitItem($aTitres, "titre".$j);
					while ($sTitre != null)
					{
						$pasTitres[] = $sTitre;
						$j++;
						$sTitre = ExtraitItem($aTitres, "titre".$j);
					}
					
					$bFirst = false;
				}
				
				// On récupère toutes les valeurs et les stoque dans le tableau $pasValeurs
				$j=1;
				$sValeur = ExtraitItem($aValeurs, "valeur".$j);
				while ($sValeur != null)
				{
					$pasValeurs[$j-1][] = str_replace(",", ".", $sValeur);
					$j++;
					$sValeur = ExtraitItem($aValeurs, "valeur".$j);
				}						
			}
			
		}
	}
?>

j’espere que ça pourra aider!! en tout merci pour la patience dont tu fais preuve pour m’aider…

function & parse(&$data){
$this->document = array();
$this->stack = array();
$this->parent = &$this->document;
return xml_parse($this->parser, $data, true) ? $this->document : NULL;
}

En php5, plus besoin de faire des retours par référence. D’une c’est moche, de deux, tu ne sais pas quelles sont les implications.

A éviter donc.

enfin à éviter :

function & parse(&$data){
		$this->document = array();
		$this->stack = array();
		$this->parent = &$this->document;
		return xml_parse($this->parser, $data, true) ? $this->document : NULL;

???

ou

function & parse(&$data){
		$this->document = array();
		$this->stack = array();
		$this->parent = &$this->document;
		return xml_parse($this->parser, $data, true) ? $this->document : [b]$null[/b];

parce que à la base, j’avais la première fonctions, que j’ai changé avec la deuxième, mais toujours le même soucis…

Vire le &parse.

function parse(&$data){
		$this->document = array();
		$this->stack = array();
		$this->parent = &$this->document;
		return xml_parse($this->parser, $data, true) ? $this->document : NULL;

Edité le 26/08/2009 à 20:35

Oh que si c’est moche. Pour commencer, tu ne sais pas ce que tu modifie (variable locale ?? globale ???), et ensuite tu casses complétement le mécanisme de visibilité inhérent à PHP & à la POO (quid si ton membre est private ? Tu fais quoi, tu modifie quand même ? et qui peut modifier ? n’importe qui).

Je peux comprendre l’intérêt du passage par référence, l’ayant utilisé moi même, mais le retour non.

Sauf à obscurcir le code, je ne vois franchement pas l’intérêt - si ce n’est pour copier le père C++ (ou c’est aussi possible, et ou c’est aussi mal, mais y a pas de garbage collector, et même dans ces cas là, vaut mieux passer par des SmartPointer).

merci, nickel, j’ai plus la notice, mais comme je n’ai pas pour habitude de faire des choses sans chercher à comprendre, à quoi servait le ‘&’, comme je l’ai annoncé plus haut, j’ai repris le code de quelqu’un, et je ne connais pas cette partie de php-xml!!!
j’ai cherché de la doc, mais j’ai rien trouvé qui m’expliquerait clairement…

en tt cas, merci bcp!!!

Edité le 27/08/2009 à 10:56

A faire du passage par référence. Lis le lien posté par Raynor. Perso, je trouve ça très bof.

J’ai compris ton point de vue Sans-Nom, je ne faisais pas (plus) de “propagande” sur le passage par référence : je soulignais juste le fait que MiWi ne semble pas lire toutes les informations qu’on lui a déjà donné :jap:

excusez, je n’avais pas vu le lien…par ailleurs, je n’avais pas compris le principe des références…
en tout cas!! merciiiiiiiiiiiiiiiiiiiiiiii…