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

Signaler
Messages postés
514
Date d'inscription
mercredi 19 mars 2003
Statut
Membre
Dernière intervention
1 mars 2009
-
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
-
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

Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
18
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 ?
Messages postés
514
Date d'inscription
mercredi 19 mars 2003
Statut
Membre
Dernière intervention
1 mars 2009

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
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
18
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à.
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
25
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();
}
Messages postés
514
Date d'inscription
mercredi 19 mars 2003
Statut
Membre
Dernière intervention
1 mars 2009

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
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
25
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.