Niehztog: Rausfinden, ob mit foreach iterierbar

Hallo,

kennt vielleicht jemand eine performante und möglichst elegante Möglichkeit, rauszufinden, ob ein Variableninhalt mit foreach iterierbar ist?

Grüße

Niehztog

  1. Grüße,
    is_array()
    MFG
    bleicher

    --
    __________________________-

    FirefoxMyth
  2. kennt vielleicht jemand eine performante und möglichst elegante Möglichkeit, rauszufinden, ob ein Variableninhalt mit foreach iterierbar ist?

    is_array()?

  3. kennt vielleicht jemand eine performante und möglichst elegante Möglichkeit, rauszufinden, ob ein Variableninhalt mit foreach iterierbar ist?

    Auch wenn die beiden bereits is_array() geantwortet haben, für PHP ab Version 5 darf man is_object() nicht vergessen, da auch Objekte iterierbar sind, wenn sie speziell aufbereitet wurden.

    1. Hi!

      kennt vielleicht jemand eine performante und möglichst elegante Möglichkeit, rauszufinden, ob ein Variableninhalt mit foreach iterierbar ist?
      Auch wenn die beiden bereits is_array() geantwortet haben, für PHP ab Version 5 darf man is_object() nicht vergessen, da auch Objekte iterierbar sind, wenn sie speziell aufbereitet wurden.

      is_object() reicht da aber auch noch nicht, denn auf instanceof Iterator und IteratorAggregate sollte ebenfalls geprüft werden.
      Also wäre die Prüfung: array oder (object und (Iterator oder IteratorAggregate))

      Lo!

      1. is_object() reicht da aber auch noch nicht, denn auf instanceof Iterator und IteratorAggregate sollte ebenfalls geprüft werden.
        Also wäre die Prüfung: array oder (object und (Iterator oder IteratorAggregate))

        Ja das passt. Kann nämlich in meinem Fall tatsächlich array oder iterator (eventuell auch Objekt) sein. Danke für den Tip.

      2. Hi.

        Also wäre die Prüfung: array oder (object und (Iterator oder IteratorAggregate))

        Und fuer die Pruefung gibts das Interface Traversable.

        Viele Gruesse,
        der Bademeister

      3. Moin!

        Auch wenn die beiden bereits is_array() geantwortet haben, für PHP ab Version 5 darf man is_object() nicht vergessen, da auch Objekte iterierbar sind, wenn sie speziell aufbereitet wurden.

        is_object() reicht da aber auch noch nicht, denn auf instanceof Iterator und IteratorAggregate sollte ebenfalls geprüft werden.

        Nicht notwendig, da beide Interfaces von Traversable erben. Der Test auf dieses Interface reicht aus, um zu entscheiden, ob ein Objekt mit foreach iterierbar ist.

        Also wäre die Prüfung: array oder (object und (Iterator oder IteratorAggregate))

        is_array oder instanceof Traversable

        - Sven Rautenberg

        1. Hi!

          is_object() reicht da aber auch noch nicht, denn auf instanceof Iterator und IteratorAggregate sollte ebenfalls geprüft werden.
          Nicht notwendig, da beide Interfaces von Traversable erben. Der Test auf dieses Interface reicht aus, um zu entscheiden, ob ein Objekt mit foreach iterierbar ist.

          Das Traversable wurde ja gestern schon erwähnt, allerdings ist das theoretisch nicht in jedem Fall. Es stimmt schon, dass die beiden Interfaces Iterator und IteratorAggregate von Traversable erben, und Traversable für diesen Zweck der einfachen Prüfung vorgesehen ist, aber da es selbst keinerlei Mitglieder definiert, dürfte es für foreach schwer werden, ein Objekt zu iterieren, das allein von Traversable erbt. Praktisch stellt sich diese Frage allerdings nicht, weil es einen Fatal Error gibt, wenn man allein Traversable implementieren will.

          class Foo implements Traversable { }

          Fatal error: Class Foo must implement interface Traversable as part of either Iterator or IteratorAggregate in Unknown on line 0

          Man hat also ein Interface, das man zwar prüfenderweise verwenden es aber nicht selbst implementieren kann ... Sieht etwas verkorkst aus, aber wenn's hilft.

          Lo!

          1. Hi.

            Nicht notwendig, da beide Interfaces von Traversable erben. Der Test auf dieses Interface reicht aus, um zu entscheiden, ob ein Objekt mit foreach iterierbar ist.

            Es ist auch nicht hinreichend, auf {Iterator oder IteratorAggregate} zu prüfen, weil es natives PHP-Zeugs gibt, das iterierbar ist und Iterator(aggregate) nicht implementiert (wohl aber Traversable).

            Das Traversable wurde ja gestern schon erwähnt, allerdings ist das theoretisch nicht in jedem Fall. Es stimmt schon, dass die beiden Interfaces Iterator und IteratorAggregate von Traversable erben, und Traversable für diesen Zweck der einfachen Prüfung vorgesehen ist, aber da es selbst keinerlei Mitglieder definiert, dürfte es für foreach schwer werden, ein Objekt zu iterieren, das allein von Traversable erbt. Praktisch stellt sich diese Frage allerdings nicht [...]

            Es gibt in dem Fall mal keinen Unterschied zwischen Theorie und Praxis. Es ist der Zweck der Existenz des Interfaces Traversable, Auskunft darüber zu geben, ob ein Objekt 'traversierbar' ist. Deshalb ist das auch *die* Prüfung, die zu machen ist, wenn man eben dieses feststellen will.

            Viele Grüße,
            der Bademeister

            1. Hi!

              Es ist auch nicht hinreichend, auf {Iterator oder IteratorAggregate} zu prüfen, weil es natives PHP-Zeugs gibt, das iterierbar ist und Iterator(aggregate) nicht implementiert (wohl aber Traversable).

              Das heißt also, es gibt PHP-Zeugs, das an der Prüfung, die zu erwähntem fatalen Error führt, vorbeiprogrammiert ist?

              Es gibt in dem Fall mal keinen Unterschied zwischen Theorie und Praxis. Es ist der Zweck der Existenz des Interfaces Traversable, Auskunft darüber zu geben, ob ein Objekt 'traversierbar' ist. Deshalb ist das auch *die* Prüfung, die zu machen ist, wenn man eben dieses feststellen will.

              Nur dass man theoretisch Interfaces im Allgemeinen auch implementieren kann, praktisch dieses eine jedoch nicht selbst, sondern nur die beiden anderen, weil es sonst zum Fatal Error kommt. Ich sehe da einen Unterschied zwischen Theorie und Praxis und dass da was spezielles gebastelt wurde, um etwas Komfort zu bekommen, der mit üblichen programmiertechnischen Mitteln nicht zu erreichen ist.

              Wenn man sich sowas selbst nachbauen wollte, nützt einem das mitgliedslose Interface nicht mehr als zur Prüfung auf einen gemeinsamen Vorfahren. Aber anwenden kann man das nicht wirklich, denn ich als PHP-Anwender kann nicht mit einem Fatal Error verhindern, dass das mitgliedslose Interface in anderen Klassen implementiert wird. Somit bieten andere Klassen nichts, worauf ich mit beziehen kann. Es sei denn, ich zusätzlich prüfe auf genau definierte Nachfahren dieses Interfaces, um deren Mitglieder verwenden zu können. Nachfahren, die jemand anderes erstellt, kann ich nicht verwenden, weil ich ja deren Mitglieder nicht kenne. Und einen Fehler kann ich auch erst zur Laufzeit werfen und nicht wie PHP bei Traversable schon zur Compile-Zeit.

              Lo!

              1. Nur dass man theoretisch Interfaces im Allgemeinen auch implementieren kann,

                Na ja, was ist jetzt die Bedeutung von 'theoretisch' und 'im Allgemeinen' in diesem Satz?

                Wenn man sich sowas selbst nachbauen wollte, nützt einem das mitgliedslose Interface nicht mehr als zur Prüfung auf einen gemeinsamen Vorfahren. Aber anwenden kann man das nicht wirklich, denn ich als PHP-Anwender [...]

                Du kannst ohnehin als PHP-Anwender nichts derartiges nachbauen, was die Syntax für den Zugriff auf Daten beeinflusst, das ist nun mal 'built-in'. Dass sowas über Interfaces realisiert ist, finde ich auch reichlich beknackt. Wenn Du das sagen wolltest, dann bin ich voll auf Deiner Seite.

                Es ändert aber nichts dran, dass es so ist: wenn Du die Iterierbarkeit eines Objektes prüfen willst, dann ist 'Traversable' zu prüfen, nichts anderes. Mehr wollte ich ja gar nicht sagen.

                Viele Grüße,
                der Bademeister

                1. Hi!

                  Nur dass man theoretisch Interfaces im Allgemeinen auch implementieren kann,
                  Na ja, was ist jetzt die Bedeutung von 'theoretisch' und 'im Allgemeinen' in diesem Satz?

                  'im Allgemeinen' ist da überflüssig.

                  Du kannst ohnehin als PHP-Anwender nichts derartiges nachbauen, was die Syntax für den Zugriff auf Daten beeinflusst, das ist nun mal 'built-in'. Dass sowas über Interfaces realisiert ist, finde ich auch reichlich beknackt. Wenn Du das sagen wolltest, dann bin ich voll auf Deiner Seite.

                  Dass dafür Interfaces verwendet wurden, finde ich schon in Ordnung. Wie sonst sollte man einen anwenderdefinierbaren Iterator-Meachanismus konzipieren? Das machen andere Systeme auch nicht wesentlich anders. Es gibt was definiertes, das man implementieren muss und dann iteriert es. Nur die Sonderlocke bei Traversable ist das, worüber ich mich amüsiere.

                  Es ändert aber nichts dran, dass es so ist: wenn Du die Iterierbarkeit eines Objektes prüfen willst, dann ist 'Traversable' zu prüfen, nichts anderes.

                  Ja, dass es Traversable extra zu diesem Zweck gibt, hab ich ja gestern schon durch deine Antwort mitbekommen. Das "nichts anderes" stimmt allerdings nicht ganz, denn Iterator und IteratorAggregate kann man auch prüfen, weil das die beiden einzigen Nachfahren von Traversable sind, auf deren Mitglieder letzlich die Funktionalität basiert und weitere nicht (durch Anwenderhand) entstehen können. Aus heutiger Sicht ist also beides vom Ergebnis gleichwertig. Dass später die PHP-SPL-Entwickler in Zukunft weitere direkte Nachfahren von Traversable erstellen, halte ich für eher unwahrscheinlich, denn mit einem Iterator und einem Iterator-Lieferer sollten sich da die Möglichkeiten schon erschöpft haben.

                  Lo!