Page 1 sur 2

problème de tableau

Posté : 09 août 2007, 14:37
par béka
Décidement, les tableaux ce n'est vraiment pas mon truc.

J'ai fais ainsi afin d'avoir un tableau qui comporte tous les commentaires qu'on trouve dans des fichiers xml :
<?
$arrayComment = array();
$users = $xpUsers->query('//user[@active="1"]');
for ($i=0; $i<$users->length; $i++) {
    $idUser = $users->item($i)->getAttribute('id');
    $userReportingFile =  $cfg['ressources_root'].'/reporting/'.$idUser.'.xml';
    if ( is_file($userReportingFile) ) {
      //on ouvre le fichier
      $domUserReportingFile = new DOMDocument('1.0','UTF-8');
      $domUserReportingFile->load($userReportingFile);
      $xpUserReportingFile = new DOMXPath($domUserReportingFile);
      $commentUser = $xpUserReportingFile->query('//comment');
      for ($j=0; $j<$commentUser->length; $j++) {
        $dateComment = $commentUser->item($j)->getAttribute('date');
        $comment = $commentUser->item($j)->nodeValue;
        //echo $dateComment." : ".$comment;
        $arrayComment[$idUser]['date'] = $dateComment;
        $arrayComment[$idUser]['comment'] = $comment;
        echo "<pre>"; print_r($arrayComment); echo "</pre>";
      }
    } 
}
?>
Le ^problème, c'est qu'en faisant ainsi, j'obtiens :

Code : Tout sélectionner

Array ( [1] => Array ( [date] => 09-08-2007 [comment] => more and more information. ) ) Array ( [1] => Array ( [date] => 05-08-2007 [comment] => bad practice. Too in brief. ) )
alors que moi je voudrais un seul et unique tableau qui contient tous les commentaires et leur date du genre :

Code : Tout sélectionner

Array ( [1] => Array ( [date] => 09-08-2007 [comment] => more and more information. ) [2] => Array ( [date] => 05-08-2007 [comment] => bad practice. Too in brief. ) )
Quelqu'un pourrait-il venir à mon aide ?

Posté : 09 août 2007, 14:49
par d0m
d'après ton code, $arrayComment est un tableau général externe à la boucle c'est bien ça?

ton code

Code : Tout sélectionner

echo "<pre>"; print_r($arrayComment); echo "</pre>";
devrait donc être placé en dehors des boucles sinon tu réaffiche ton tableau pour à chaque utilisateur d'où l'impression d'en avoir 2.

Après il doit y avoir un problème d'id_user

Posté : 09 août 2007, 14:54
par béka
en l'affichant à la fin de ma boucle, je n'affiche que le dernier commentaire de mon fichier xml. C'est à dire que si un utilisateur a déposé plusieurs commentaires ainsi :

Code : Tout sélectionner

<root last_insert="1"> <reporting id="1" item_id="1"> <used>Y</used> <mark>2</mark> <comment date="09-08-2007"><![CDATA[more and more information.]]></comment> <reusable/> </reporting> <reporting id="2" item_id="3"> <used>Y</used> <mark>2</mark> <comment date="05-08-2007"><![CDATA[bad practice. Too in brief.]]></comment> <reusable/> </reporting> </root>
dans mon tableau, je n'ai que le dernier. Et ceci pour tous les fichiers xml.

Je suis alors obligé de faire ainsi pour avoir tous les commentaires de tous les utilisateurs :
<? $arrayComment[$idUser][$j]['date'] = $dateComment;
        $arrayComment[$idUser][$j]['comment'] = $comment; ?>
c'est pas terrible mais à lalimite laissons. Ensuite, je voudrais faire un tri sur l'attribut date : afficher les plus récents en premiers quelque soit l'id de l'utilisateur (à la limite, je pourrais presque m'en passer dans mon tableau) mais alors là, un tableau a 3 dimensions.. pffff galère.

Posté : 09 août 2007, 15:02
par Ryle
Tu n'aurais pas un soucis ici :
 for ($j=0; $j<$commentUser->length; $j++) { 
        $dateComment = $commentUser->item($j)->getAttribute('date'); 
        $comment = $commentUser->item($j)->nodeValue; 
        //echo $dateComment." : ".$comment; 
        $arrayComment[$idUser]['date'] = $dateComment; 
        $arrayComment[$idUser]['comment'] = $comment; 
        echo "<pre>"; print_r($arrayComment); echo "</pre>"; 
      } 
Tu écrases continuellement les valeurs $arrayComment[$idUser]['date'] et $arrayComment[$idUser]['comment']. Ton tableau ne contiendra au final que les dernières valeurs de la boucle.
if (!isSet($arrayComment[$idUser])) // déclaration du sous-tableau par user
  $arrayComment[$idUser] = array();

// ajoute l'élément au sous-tableau.. idem array_push()
$arrayComment[$idUser][] = array( 
                            'date' => $dateComment,
                            'comment' => $comment
                           );

Posté : 09 août 2007, 15:08
par béka
ce que tu me propose Ryle, ca revient au même que ce que j'ai fait dans mon post précédent non ?
<? $arrayComment[$idUser][$j]['date'] = $dateComment;
        $arrayComment[$idUser][$j]['comment'] = $comment; ?>
en faisant ainsi, j'ai ca :

Code : Tout sélectionner

Array ( [1] => Array ( [0] => Array ( [date] => 09-08-2007 [comment] => more and more information. ) [1] => Array ( [date] => 05-08-2007 [comment] => bad. Too in brief. ) ) [2] => Array ( [0] => Array ( [date] => 06-08-2007 [comment] => test comment. ) [1] => Array ( [date] => 08-08-2007 [comment] => bad bouh. ) ) )
-> là j'ai bien tous les commentaires.

Mais quand j'essai de les trier en fonction de la date comme ci-dessous, ca ne marche pas, pourquoi ?
<?
foreach ($arrayComment as $key => $row) {
                          $tab_date[$key]    = $row['date'];
                          $tab_comment[$key]    = $row['comment'];
                        }
array_multisort($tab_date, SORT_DESC, $arrayComment ); 
echo "<pre>"; print_r($arrayComment); echo "</pre>";
?>

Posté : 09 août 2007, 15:13
par d0m
et pourquoi pas un tableau contenant tous les commentaires de ce genre :

Code : Tout sélectionner

[0] => Array ( [user] => 1 [date] => 09-08-2007 [comment] => more and more information. ) [1] => Array ( [user] => 1 [date] => 05-08-2007 [comment] => bad. Too in brief. )
si de toute facon le regroupement par user ne t'interesse pas beaucoup.
Cela te permettrait de trier par date beaucoup plus facilement

Posté : 09 août 2007, 15:17
par d0m
Mais quand j'essai de les trier en fonction de la date comme ci-dessous, ca ne marche pas, pourquoi ?
parce que tu t'es perdu dans ton tableau :
foreach ($arrayComment as $key => $row)
affiche $row et tu comprendras que c'est un tableau qui ne contient pas les index 'comment' et 'date', c'est encore un niveau au dessus dans le tableau.

Posté : 09 août 2007, 15:20
par béka
et comment créer le tableau que tu me propose alors ?

Posté : 09 août 2007, 15:48
par d0m
c'est très simple. Dans ton code, tu modifie ton tableau qu'à un seul endroit, ici :
$arrayComment[$idUser]['date'] = $dateComment; 
$arrayComment[$idUser]['comment'] = $comment;

//ou

$arrayComment[$idUser][$j]['date'] = $dateComment; 
$arrayComment[$idUser][$j]['comment'] = $comment; ?>
c'est à cet endroit que tu définis toute la structure de ton tableau $arrayComment.

Il suffit donc de remplacer ces lignes par le code approprié pour la structure de ton tableau.
$arrayComment[] = array('idUser'   => $idUser,
                        'date'     => $dateComment,
                        'comment'  => $comment);
chaque élement de ton tableau étant un commentaire d'un utilisateur donné à une date donné

Posté : 09 août 2007, 15:53
par béka
c'est très simple.
non :D
Je pige rien au tableau, je galère toujours en php lorsque je dois faire des tableaux.

En tout cas, merci, c'est juste ce que je voulais.
Ensuite lorsque je souhaite en afficher 3 par exemple, je fais ainsi :
<?
$i=0;
                        echo "<br>";
                        foreach ($arrayComment as $key=>$value){
                            if ( $i == 3) { break; }
                            else {
                              $comment = $date['comment'];
                              $date = $date['date'];
                              echo $date." : ".$comment."<br><br>";
                            }
                            $i++;
                        }
?>
Donc là ca marche, mais je ne comprends pas ce code, peux-tu me l'expliquer (que je ne l'utilise pas sans le comprendre)

Posté : 09 août 2007, 16:04
par Ryle
ce que tu me propose Ryle, ca revient au même que ce que j'ai fait dans mon post précédent non ?
Euh ouep, en effet, tu n'avais pas encore posté ce message et j'étais donc parti de ton premier post :)

Pour les tableaux, c'est pas dur.. imagine toi une simple ligne avec plusieurs cases. Dans chaque case (identifiée par un index numérique ou par du texte dans le cas d'un tableau associatif) tu peux mettre n'importe quoi, y compris un nouveau tableau et ça te donne un tableau à 2 dimensions, etc... c'est pas plus compliqué que ça :)

Quant à la lecture : "foreach ($arrayComment as $key=>$value)" équivaut à "Pour chaque élément du tableau $arrayComment, considerant l'index (ou clé) dans la variable $key et la valeur associée dans $value, exécuter le code suivant."

Le break te permettant d'interrompre le code et de sortir de la boucle :)

Posté : 09 août 2007, 16:08
par béka
oui le break je savais. C'est juste la syntaxe

foreach ($arrayComment as $key=>$value) que j'ai du mal a assimiler.

Le reste de cette boucle, ca va.

En tout cas, merci à vous deux.

Je vais me lancer dans un autre tableau pour autre chose... je vais essayer de me débrouiller seul.


EDIT
c'et encore moi,

j'ai une question. Comment peut-on vérifier si une variable est déjà présente dans un tableau multidimensionnel.

J'ai fait ainsi mais sans succès :
<?
for ($i=0; $i<$itemOn->length; $i++) {
    $usId = $itemOn->item($i)->getAttribute('usId');
    $user = $xpUsers->query('//user[@id="'.$usId.'"]');
    $nameUser = $user->item(0)->getAttribute('name');
    $firstnameUser = $user->item(0)->getAttribute('firstname');
    if ( in_array($usId, $arrayUsId) ) continue;
    $arrayUsId[$i]['usId'] = $usId;
    $arrayUsId[$i]['name'] = $nameUser;
    $arrayUsId[$i]['firstname'] = $firstnameUser;
}
echo "<pre>"; print_r($arrayUsId); echo "</pre>";
?>
Quelqu'un sait-il ou a-t-il une solution alternative ?

Posté : 10 août 2007, 08:24
par d0m
pas de in_array dans ce cas puisque conceptuellement tu ne va pas vraiment vérifier si la variable est dans le tableau mais plutôt si la variable est la valeur d'un champ spécifique d'un élement.
Pour imager c'est comme si tu cherchais une paire de chaussures et que tu n'as pas une liste de chaussure mais une liste de personnes à qui il faut demander si elles portent ces chaussures.

ça serait donc un truc du genre :
$existe_deja = false;
foreach($arrayUsId as $utilisateur){
  if( $utilisateur['usId'] == $usId ){
    $existe-deja = true;
    break; 
  }
}

Posté : 10 août 2007, 09:07
par béka
et ce code que tu propose d0m est à placer où ?

Posté : 10 août 2007, 09:21
par d0m
et ce code que tu proposes est à placer où ?
Tout dépend de ce que tu veux faire.
Si tu veux modifier par exemple les données de l'élement que tu cherches, tu mettras du code après le if, etc.
Là c'est juste la recherche de l'élement pour le reste tu devrais t'en tirer.