2017-09-22 1 views
2

PHP 7.1 a ajouté la nouvelle fonction is_iterable pour vérifier si une variable peut être itérée. Mais bien que vous puissiez itérer sur les propriétés d'un objet, is_iterable renvoie false pour eux.Pourquoi les objets ne sont-ils pas considérés comme itératifs alors qu'ils le sont réellement?

Cela semble être intentionnel, car il est documenté et je n'ai pas trouvé de bogues PHP concernant le problème, mais je me demande pourquoi cela a été fait?

<?php 
$a = new stdClass(); 
$a->foo = 'bar'; 

var_dump(is_iterable($a)); 

foreach ($a as $key => $value) { 
    var_dump($key, $value); 
} 

Sorties

boolean false 
string 'foo' (length=3) 
string 'bar' (length=3) 

Mais j'attendre à la sortie

boolean true 
string 'foo' (length=3) 
string 'bar' (length=3) 

Répondre

3

C'est une question de définition, et "pourquoi est-il fait" est une question délicate, probablement mieux pour les développeurs PHP.

Mais quelques informations: Vous pouvez foreach sur un objet, et il affiche les properies visibles selon the manual

PHP 5 fournit un moyen pour les objets à définir de sorte qu'il est possible de parcourir une liste d'éléments, avec, par exemple, une instruction foreach. Par défaut, toutes les propriétés visibles seront utilisées pour l'itération.

Le is_iterable est la vérification des choses spécifiques, voir the manual

Vérifiez que le contenu d'une variable est acceptée par le itérables pseudo type, à savoir qu'il est un tableau ou un objet implémentant Traversable

un objet ne pas mettre en œuvre Traversable si vous ne le faites pas vous-même (et n'est pas l'un des « autres » mince gs, comme un tableau) donc ce n'est pas "itérable" dans ce sens.

Longue histoire courte: foreach peut itérer sur tout ce qui est itérable, mais tout ce que foreach peut itérer n'est pas appelé itérable. C'est une chaise-a-4-jambes vs tout-avec-4-jambes-est-une sorte de chaise. Je verrais le fait que vous pouvez itérer sur un objet sans implémenter explicitement itérable est une sorte d'exception, et laissez-le à cela. La seule autre réponse serait "ils l'ont fait parce que".

+2

Cela semble à peu près juste pour une réponse liée à PHP ... meh ¯ \\ _ (ツ) _/¯. – deceze

+0

* Un objet n'implémente pas Traversable si vous ne le faites pas vous-même * et * Ceci est une interface moteur interne qui ne peut pas être implémentée dans les scripts PHP. * Http://php.net/manual/fr/class.traversable .php. Une impasse? –

+2

@Alex Phrase suivante: * "Soit' IteratorAggregate' ou 'Iterator' doit être utilisé à la place." * (Note: les deux sont des sous-classes de 'Traversable' ...) – deceze