[SPL] Une variable objet comme clé de l'interface Iterator

LocalStone Messages postés 514 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 1 mars 2009 - 21 nov. 2007 à 01:31
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 - 22 nov. 2007 à 11:15
Salut à tous,
Alors voilà ma question : est-il possible d'utiliser l'interface Iterator (ou tout interface qui permettent le parcours d'un objet avec un foreach) de telle manière à ce que la clé retournée soit un objet. Imaginons par exemple un objet de type Map, à la manière de Java : on fait foreach($objMaMap as $objMaCleObjet => $mxdMaVariable) ... Parce qu'après avoir essayé, j'ai eu une erreur qui me dit que le type de retour n'est pas convenable ...
Merci pour vos réponses !

LocalStone

6 réponses

neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
21 nov. 2007 à 02:26
Salut,

Quand on fait :
foreach ($objMaMap as $objMaCleObjet => $mxdMaVariable)

$objMaMap est l'itérateur, $objMaCleObjet est ce que retourne la méthode key() de l'itérateur, et $mxdMaVariable ce que retourne current()

key() doit, en toute logique, retourner un scalaire (le plus souvent un entier ou une chaine de caractères). current() par contre peut retourner n'importe quel type de variable.

J'ai par exemple un itérateur pour gérer mes fichiers de configuration. J'ai deux niveau : la racine (la configuration générale) et des modules.
Quand j'itère sur mon itérateur config, il me renvoit des objets configModule.

"Parce qu'après avoir essayé, j'ai eu une erreur qui me dit que le type de retour n'est pas convenable ..."
Que disait précisément le message d'erreur ?
0
LocalStone Messages postés 514 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 1 mars 2009
21 nov. 2007 à 17:10
Alors de tête, comme ça en speed, c'était Illegal Type Returned From MaMap::key() ... Je crois que c'est ça.
Je vais essayer de poster le script qui pose problème le plus vite possible, mais d'ici là ... Si quelqu'un à une idée quand même ...

LocalStone
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
21 nov. 2007 à 17:32
Ah oui ok...

Bon la doc PHP de la fonction ley() n'est pas très très explicite, pas plus que la doc de la SPL... Pas facile de savoir quel type de variable elle doit retourner.

J'ai tendance à penser qu'il faut que ce soit un certain scalaire (typiquement int ou string, mais peut-être que float est autorisé).
Après tout, c'est un index, et utiliser un objet ou un tableau comme index n'a pas de sens.

Par contre, current() peut retourner n'importe quel type de variable : scalaire ou non, objet, array, etc. Aucune limitation à ce niveau là.
0
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
21 nov. 2007 à 19:59
Hello,

non c'est impossible. Je ne comprends même pas comment tu as pu te débrouiller pour en arriver là, parce qu'à la déclaration de ton objet itérateur, ça devrait planter. Exemple :
<?php
$oV = new ArrayIterator(array(1,2,3));
$oK = new ArrayIterator (array(4,5,6));
$oTest = new ArrayIterator(array (
    $oK => $oV)
);
foreach($oTest as $oK => $oV) {
    echo $oK;
}
?>
Ca ne plante pas sur le foreach(), mais sur la déclaration de $oTest.
Ensuite je vois mal l'intérêt ?
Imaginons que $o est un objet étendant ArrayIterator et possèdant une méthode lambda? Et que mon objet test soit un ArrayObject dans lequel on stocke des $o. Je pêux alors faire :
foreach($test as $o) {
  $o->lambda();
}
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
LocalStone Messages postés 514 Date d'inscription mercredi 19 mars 2003 Statut Membre Dernière intervention 1 mars 2009
21 nov. 2007 à 23:35
Bah en fait, j'ai une classe Map qui implémente l'interface Iterator, donc c'est normal que l'interpréteur ne mais rien dit avant l'execution.
Euh ... Du coup, vous avez pas une solution élégante pour palier à ce manque ? Le propre d'une map est de pouvoir utiliser des clefs de n'importe quelle type, et je ne vois pas pourquoi on pourrait pas la traverser.
En fait, l'idéal serait de définir une class MapEntry qui possède 2 méthode : getKey() et getValue(). Et en fait, on fasse quelque chose du genre :
foreach($objMap as $objMapEntry) {
    $mxdValue = $objMapEntry -> getValue();
    $mxdKey = $objMapEntry -> getKey();
}
Mais y a t-il une interface qui permette le parcours d'objet à la manière de Iterator, sans devoir implémenter la méthode key() ?

LocalStone
0
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
22 nov. 2007 à 11:15
Non, key() est nécessaire. Elle fait partie de l'interface de base : Iterator.
Mais tu as effectivement ArrayObject qui permet le parcours d'un objet.
0
Rejoignez-nous