7764 sujets

Développement web côté serveur, CMS

Pages :
Bonjour,

Alors dans le cadre de récupérations de variables par l’intermédiaire d'un fichier XML, jusqu'à maintenant tout fonctionne parfaitement :

J'ai simplifié le code d'origine pour l'exemple :

if(!isset($xml->{'table_xml'}->{'var_1'})) {$var_1 = '∅';$var_1_bis = '∅';}
else{foreach($xml->table_xml->var_1 as $var_1);
$var_1_bis = $var_1 + 42;}


On a donc une récupération de variable sous plusieurs formes :
$var_1
$var_1_bis
$xml->table_xml->var_1
$xml->{'table_xml'}->{'var_1'}

var_1 ayant une valeur chiffré contenu dans le fichier xml que je récupère. Sinon il affichera à la place ∅

Et comme j'en ai environ une 100aine à passer, je me dis que plutôt que de taper ça 100 fois, autant faire une incrémentation de la valeur dans une boucle for.

Je me suis donc renseigné sur les variables dynamiques que je ne connaissais absolument pas et j'aimerais savoir si ma méthode est la bonne et si c'est correct. J'ai essayé avant dans un array mais ça fonctionnait pas du tout, je ne sais pas pourquoi d'ailleurs.

for ($i = 1; $i <= 100; $i++) {

$var_i = 'var_'.$i; 
$var_i_bis = $var_i.'_bis';

if(!isset($xml->{ 'table_xml' }->{ $var_i })) { $$var_i = '&#8709;'; $$var_i_bis = '&#8709;'; }
else{foreach($xml->table_xml-> $var_i as $$var_i);
$$var_i_bis = $$var_i + 42;}
}


Merci pour vos renseignements
Modifié par Damien49 (29 Nov 2018 - 19:10)
Salut

Attention, tu utilise un double dollars sur ta variable...
haha, je ne connaissais pas cette syntaxe autant pour moi... Smiley smile

j'utilise des ".=" pour cela..

je te conseil d'utiliser des var_dump() sur tes variables, voir s'ils elles existent/sont remplies.
Ok je vois pour les variable dynamique.. mais dan ton cas, à quoi sert cela ??
tu as juste besoin d'incrementer ton "nom" de fonction. pas de rendre dynamique celle ci.

J'ai l'impression que ce genre de syntaxe équivaut aux "&" que l'ont peut retrouver lors des assignation de mémoire.
Du coup je comprend pas cela dans ton cas.
ton $$var_i signifie donc (si je suis la doc) que la valeur de $var_i est une variable en soit et que donc $$ va chercher la valeur de la variable référence dans $.. donc je comprend pas ton cas. car toi tu cherches juste à jouer sur les "noms" des variable.
Modifié par JENCAL (30 Nov 2018 - 11:45)
Oui c'est cela, je cherche juste à changer/incrémenter le nom de la variable, ensuite quand je mets le double $$, là je vais chercher vraiment la valeur de la variable qui se trouve dans mon fichier xml en amont.

J'ai fait quelques tests ça l'air de fonctionner en fait. Mais y'a surement plus simple en effet. J'avais essayé avant avec un array, mais ça fonctionnait pas du tout.

Un exemple simple, qui m'a servi de modèle en fait :

$var_1 = 'A';
$var_2 = 'B';
$var_3 = 'C';

for ($i = 1; $i <= 3; $i++) {

$var_i = 'var_'.$i; 
echo $$var_i;

}

Modifié par Damien49 (30 Nov 2018 - 12:04)
pourquoi ne pas utiliser un tableau, plutôt que de prendre des risques avec les variables dynamiques?


$var = [];
$var[] = 'A';
$var[] = 'B';
$var[] = 'C';

for ($i = 0; $i < count($var); $i++) {
  echo $var[i];
}

// ou pour un tableau non continu:

$var = [];
$var[2] = 'A';
$var[13] = 'B';
$var[18] = 'C';
foreach ($var as $key => $value) {
  echo $key . ' - ' . $value;
}
JENCAL a écrit :
J'ai l'impression que ce genre de syntaxe équivaut aux "&amp;" que l'ont peut retrouver lors des assignation de mémoire.

Non, & existe aussi un php. $$ crée un nom de variable dynamique, ce qui peut potentiellement être dangereux, autrement dit $$truc convertit $truc en chaine et appelle la variable avec ce nom. Si $truc provient d'un valeur utilisateur ou non sûre, c'est très dangereux.

Il faut les éviter le plus possible ou les limiter dans des cas très spécifiques, idéalement isolé dans une fonction propre dans laquelle on ne peut pas usurper d'autres noms de variables.
Oui mais au final, ta variable dynamique doit exister, enfin je veux dire, celle qui est référencé par $$ ?

$a = "a";
$b = "c";

$$b plante non ?

$a = "b";
$b = "a";

$$b passe bien non ?

oui le & existe déjà, mais ayant du mal à comprendre l'utilité des variables dynamique

$a = "mymethod";
$obj->$a() fonctionne aussi donc bon...
J'ai essayé avec un tableau comme je l'ai dit, mais ça ne fonctionnait pas. Peut-être parce que je récupère les données d'un fichier XML je ne sais pas. A partir de ton exemple comment convertir mon 1er code ?

if(!isset($xml->{'table_xml'}->{'var_1'})) {$var_1 = '&#8709;';$var_1_bis = '&#8709;';}
else{foreach($xml->table_xml->var_1 as $var_1);
$var_1_bis = $var_1 + 42;}


y'a aussi le fait que mon incrémentation $i se fait en milieu de nom de variable dans une partie de mon code et que ça je ne peux pas le changer (à moins de devoir réécrire 30000 lignes de codes) :

$var_1
$var_1_bis

donc ok pour le $var_[$i] mais pour le $var_[$i]_bis là c plus compliqué ^^

(évidemment j'ai simplifier les noms et mon code pour l'exemple)
Modifié par Damien49 (30 Nov 2018 - 14:40)
Oui c'est semblable aux noms de méthodes dynamiques, sauf qu'on ne peut appeler que des méthodes déjà définies, les noms de variables dynamique permettent aussi de les initialiser ou d'écraser des variables existantes:

$b = "c";
$$b = "truc"; // est équivalent à $c = "truc";

En s'en prenant aux sources, on peut éventuellement réécrire des variables (aux noms comme $is_admin ou $sql par exemple) qui sont dans la même portée.
Dans l'exemple ici le risque est limité vu que le nom dynamique est connu et limité (var_n et var_n_bis), mais ça reste qqch de difficile à débugger et peut facilement amener des failles suite à une inattention ou une modification.
@Damien49
Ton code en fait n'a à peu près aucun sens, difficile de t'aider, voici la transcription de ton code avec des tableaux:


$var = [];
for ($i = 1; $i <= 100; $i++) { 
  if(!isset($xml->{ 'table_xml' }->{ 'var_'.$i })) {
    $var[$i] = '&#8709;';
    $var_bis[$i]  = '&#8709;';
  }
  else{
    $var[$i]  = end($xml->{ 'table_xml' }->{ 'var_'.$i });
    $var_bis[$i] = $var[$i] + 42;
  }
}
Bon j'ai tenté un truc :

$var_ = [];
for ($i = 1; $i <= 100; $i++) {

if(!isset($xml->{ 'table_xml' }->{ 'var_'.$i })) { $var_[$i] = '&#8709;'; ${$var_[$i].'_bis'} = '&#8709;'; }
else{foreach($xml->{ 'table_xml' }-> { 'var_'.$i } as $var_[$i]);
${$var_[$i].'_bis'} =  $var_[$i]+42 ;

}	


J'obtiens le même résultat que ton code, à savoir

Undefined variable: var_1
Undefined variable: var_1_bis
Undefined variable: var_2
Undefined variable: var_2_bis
etc...

quand j'appelle ensuite mes echo $var_1 ; et $var_1_bis

Y'a un truc qui cloche quand je passe ça en tableau.
Modifié par Damien49 (30 Nov 2018 - 15:14)
Il n'y a aucun problème avec les tableaux. Ton problème est ailleurs. Oublie complètement les variables dynamiques,

là tu cherches à afficher $var_1 et $var_1_bis et aucune n'existe dans ton code, ce qui existe dans ce que tu as écris c'est $var[1] et (attention) $&#8709;1

Je ne comprends pas non plus ton foreach (qui n'a aucun sens, si tu veux le dernier élément d'un tableau utilise end()) et utiliser « as $var_[$i] » n'est en effet pas possible.
Le code complet (un peu simplifié) est le suivant :

fichier XML :
<table_xml>
<var_1>2.1</var_1>
<var_2>12.5</var_2>
<var_3>15.8</var_3>
<var_4>35.4</var_4>
<var_5>8.2</var_5>
<var_6>-1.3</var_6>
etc...
</table_xml>


//j’appelle mon fichier XML
$file = file_get_contents('http://adresse_de_mon_fichier_xml');
$xml=simplexml_load_string($file);

//je lis les valeurs de mon fichier XML

//si je ne trouve rien, j'affiche un signe d'erreur (https://www.fileformat.info/info/unicode/char/2205/index.htm)
if(!isset($xml->{'table_xml'}->{'var_1'})) {
$var_1 = '&#8709;';
$var_1_bis = '&#8709;';
}

//si je trouve quelque-chose dans mon fichier XML, j'affiche la valeur dans une variable
else{
foreach($xml->table_xml->var_1 as $var_1);

//conversion de la valeur dans une autre norme
$var_1_bis = round((5/9) * (floatval( $var_1 ) - 32),1);}
}

//on refait la même chose avec $var_2 et $var_2_bis (si je ne trouve rien, j'affiche un sigle d'erreur et si je trouve une valeur, je la met dans une variable) etc...


//j'appelle mes valeurs : 
echo $var_1 ; 
echo $var_1_bis ; 
echo $var_2 ; 
echo $var_2_bis ; 
//etc...


Enfin voilà. Pour l'instant ça marche parfaitement si je n'incrémente pas mes valeurs en tapant 100 fois le même code et si j'utilise les variables dynamiques. Smiley decu
Modifié par Damien49 (30 Nov 2018 - 16:05)
pour moi le problème est là

foreach($xml->table_xml->var_1 as $var_1)


je verrais plutot
foreach($xml->table_xml as $var)
{
 // et la tu as toutes tes cles/valeurs.
}
Le probleme c'est que le fichier XML est bcp plus complexe que ce que je vous ai donné.

Il ressemble plutôt à ça

<table_xml>
<machin>truc</machin>
<var_1>2.1</var_1>
<var_2>12.5</var_2>
<var_3>15.8</var_3>
<var_4>35.4</var_4>
<var_5>8.2</var_5>
<var_6>-1.3</var_6>
<machin_chose>lorem</machin_chose>
<bidule_1>blabla</bidule_1>
<bidule_2>blabla</bidule_2>
<bidule_3>blabla</bidule_3>
<trucmuche>14°C</trucmuche>
etc..il fait plusieurs milliers de lignes très diverses ^^
</table_xml>

quand je récupère les données j'essaye donc de faire un truc propre et d'assigner une variable à chaque catégorie dans le fichier xml.
Modifié par Damien49 (30 Nov 2018 - 16:18)
Tu peux pas mettre une condition dans ta boucle sur table_xml genre
if ($key.constains("var_")
{
//traitement de var_X
}

EDIT : voir message en dessous.
Modifié par JENCAL (30 Nov 2018 - 16:18)
En gros.
foreach($xml->table_xml as  $key => $value)
{
   if (strpos(key , 'var_') !== false) {
      // je recupe la value. et je fais mon traitement.
    }
}
a écrit :
Il ressemble plutôt à ça

Il ressemble plutôt à rien. Si c'est ton format, essaie de le modifier en qqch d'exploitable:

<table_xml>
<machin>truc</machin>
<vars>
  <var key="1">2.1</var>
  <var key="2">12.5</var>
  <var key="3">15.8</var>
  <var key="4">35.4</var>
  <var key="5">8.2</var>
  <var key="6">-1.3</var>
</vars>
<machin_chose>lorem</machin_chose>
<bidules>
  <bidule key="1">blabla</bidule>
   … etc.

Si ce n'est pas possible boucler sur des milliers de ligne ne sera pas pertinent en effet.


$var = [];
for ($i = 1; $i <= 100; $i++) { 
  if(!isset($xml->{ 'table_xml' }->{ 'var_'.$i })) {
    $var[$i] = '&#8709;';
    $var_bis[$i]  = '&#8709;';
  }
  else{
    $var[$i]  = (float) $xml->{ 'table_xml' }->{ 'var_'.$i };
    $var_bis[$i] = $var[$i] + 42;
  }
}

echo $var[1];
echo $var_bis[1];
echo $var[2];
echo $var_bis[2];