Unterschied zwischen ArrayIterator, ArrayObject und Array in PHP

Lesezeit: 13 Minuten

Benutzer-Avatar
Jkhamler

Kann jemand die grundlegenden Unterschiede zwischen deutlich erklären ArrayIterator, ArrayObject und Array in PHP in Bezug auf Funktionalität und Bedienung? Vielen Dank!

  • Hast du gelesen ArrayIterator, ArrayObject und Array? Das sind wahrscheinlich alle Informationen, die Sie brauchen.

    – Vascowhite

    8. Mai 2012 um 16:48 Uhr

Benutzer-Avatar
Mridul Aggarwal

Array ist ein nativer PHP-Typ. Sie können eine mit dem PHP-Sprachkonstrukt erstellen array()oder ab PHP 5.4 []

ArrayObject ist ein object die genau wie Arrays funktionieren. Diese können mit erstellt werden new Stichwort

ArrayIterator ist wie ArrayObject aber es kann sich selbst wiederholen. Auch erstellt mit new


Vergleichen Array gegen (ArrayObject/ArrayIterator)

Sie können beide mit der Array-Syntax von PHP verwendet werden, z.

$array[] = 'foo';
$object[] = 'foo';
// adds new element with the expected numeric key

$array['bar'] = 'foo';
$object['bar'] = 'foo';
// adds new element with the key "bar"

foreach($array as $value);
foreach($object as $value);
// iterating over the elements

Sie sind jedoch immer noch Objekte und Arrays, sodass Sie die Unterschiede in bemerken würden

is_array($array); // true
is_array($object); // false

is_object($array); // false
is_object($object); // true

Die meisten PHP-Array-Funktionen erwarten Arrays, daher würde die Verwendung von Objekten dort Fehler auslösen. Es gibt viele solcher Funktionen. Für zB.

sort($array); // works as expected
sort($object); // Warning: sort() expects parameter 1 to be array, object given in ......

Schließlich können Objekte das tun, was Sie von a erwarten würden stdClass Objekt, dh Zugriff auf öffentliche Eigenschaften unter Verwendung der Objektsyntax

$object->foo = 'bar'; // works
$array->foo = 'bar'; // Warning: Attempt to assign property of non-object in ....

Arrays (als nativer Typ) sind viel schneller als Objekte. Auf der anderen Seite die ArrayObject & ArrayIterator Für Klassen sind bestimmte Methoden definiert, die Sie verwenden können, während es so etwas für Arrays nicht gibt


Vergleichen ArrayObject vs ArrayIterator

Der Hauptunterschied zwischen diesen 2 liegt in den Methoden, die die Klassen haben.

Das ArrayIterator implementiert Iterator -Schnittstelle, die ihr Methoden zur Iteration/Schleife über die Elemente gibt. ArrayObject hat eine Methode namens exchangeArray das tauscht sein internes Array mit einem anderen aus. Implementieren einer ähnlichen Sache in ArrayIterator würde bedeuten, entweder ein neues Objekt zu erstellen oder die Tasten & zu durchlaufen unseting sie alle nacheinander und setzen Sie dann die Elemente aus dem neuen Array nacheinander.

Als nächstes, da die ArrayObject kann nicht iteriert werden, wenn Sie es in verwenden foreach es schafft ein ArrayIterator Objekt intern (wie Arrays). Das heißt, php erstellt eine Kopie der Originaldaten & es gibt jetzt 2 Objekte mit gleichem Inhalt. Dies wird sich für große Arrays als ineffizient erweisen. Sie können jedoch angeben, welche Klasse für den Iterator verwendet werden soll, sodass Sie benutzerdefinierte Iteratoren in Ihrem Code haben können.

  • Die Erklärung ist, dass der ArrayIterator alles falsch ist. Lesen Sie meine Antwort.

    – David

    20. Dezember 2014 um 10:36 Uhr

  • @David Was ist falsch an den geposteten Informationen?

    – Manny Fleurmond

    6. Dezember 2020 um 20:59 Uhr

ArrayObject und Array sind etwas ähnlich. Lediglich eine Sammlung von Objekten (oder nativen Typen). Sie haben einige verschiedene Methoden, die Sie aufrufen können, aber es läuft meistens auf dasselbe hinaus.

Ein Iterator ist jedoch etwas ganz anderes. Das Iterator-Entwurfsmuster ist eine Möglichkeit, Ihr Array zu sichern (es nur lesbar zu machen). Nehmen wir das nächste Beispiel:

Sie haben eine Klasse, die ein Array hat. Sie können diesem Array Elemente hinzufügen, indem Sie addSomethingToMyArray verwenden. Beachten Sie jedoch, dass wir etwas mit dem Element tun, bevor wir es tatsächlich zum Array hinzufügen. Dies könnte alles sein, aber lassen Sie uns für einen Moment so tun, als wäre es sehr wichtig, dass diese Methode für JEDES Element ausgelöst wird, das wir dem Array hinzufügen möchten.

class A
{
    private $myArray;
    public function returnMyArray()
    {
        return $this->myArray;
    }

    public function addSomethingToMyArray( $item )
    {
        $this->doSomethingToItem( $item ); 
        array_push( $item );
    }
}

Das Problem dabei ist, dass Sie das Array hier als Referenz übergeben. Das bedeutet, dass Klassen, die tatsächlich returnMyArray verwenden, das echte myArray-Objekt erhalten. Das bedeutet, dass andere Klassen als A Dinge zu diesem Array hinzufügen und daher auch das Array in A ändern können, ohne das addSOmethingToMyArray verwenden zu müssen. Aber wir mussten etwas für den Gegenstand tun, erinnerst du dich? Dies ist ein Beispiel für eine Klasse, die ihren eigenen inneren Status nicht unter Kontrolle hat.

Die Lösung dafür ist ein Iterator. Anstatt das Array zu übergeben, übergeben wir das Array an ein neues Objekt, das nur Dinge aus dem Array LESEN kann. Der einfachste Iterator aller Zeiten sieht so aus:

<?php

class MyIterator{

    private $array;
    private $index;

    public function __construct( $array )
    {
        $this->array = $array;
    }

    public function hasNext()
    {
        return count( $this->array ) > $this->index;
    }

    public function next()
    {
        $item = $this->array[ $this->index ];
        this->$index++;

        return $item;
    }       
}

?>

Wie Sie sehen können, habe ich keine Möglichkeit, dem angegebenen Array neue Elemente hinzuzufügen, aber ich habe Möglichkeiten, das Array wie folgt zu lesen:

while( $iterator->hasNext() )
    $item = $iterator->next();

Nun gibt es wieder nur eine Möglichkeit, Items zu myArray in A hinzuzufügen, nämlich über die Methode addSomethingToArray. Das ist also ein Iterator, er ist so etwas wie eine Hülle um Arrays herum, um etwas bereitzustellen, das Kapselung genannt wird.

  • ArrayObject implementiert IteratorAggregate und ist als solcher selbst (externer) Iterator.

    – Seltenst

    6. Februar um 19:48 Uhr

Benutzer-Avatar
XuDing

array ist einer der acht primitiven Typen in PHP. Obwohl es viele eingebaute Hilfsfunktionen enthält, sind sie alle prozedural.

Beide ArrayObject und die ArrayIterator erlauben uns, Arrays zu erstklassigen Bürgern in einem objektorientierten Programm (OOP) zu machen.

Unterschied zwischen ArrayObject und die ArrayIterator ist das, da ArrayIterator implementiert SeekableIterator Schnittstelle, können Sie tun $myArray->seek(10); mit ArrayIterator.

Ein Iterator ist ein Objekt, das es einem Programmierer ermöglicht, einen Container zu durchlaufen, insbesondere Listen. Über die Schnittstelle eines Containers werden häufig verschiedene Arten von Iteratoren bereitgestellt.

Es gibt keinen großen Unterschied zwischen ArrayObject und Array da sie dieselben Dinge darstellen, obwohl sie unterschiedliche Objekttypen verwenden.

ArrayIterator ist ein Iterator, der iteriert Array-like Objekte, dazu gehören alle Objekte, die implementieren ArrayAcess und der Eingeborene Array Typ. In der Tat, wenn Sie foreach über ein Array erstellt PHP intern ArrayIterator Um die Traversierung durchzuführen und Ihren Code so umzuwandeln, dass er so aussieht, als wäre dies eingegeben worden,

for( $arrayIterator->rewind(); $arrayIterator->valid(); $arrayIterator-
>next())
{    $key = $arrayIteartor->key();
     $value = $arrayIterator->current();
}

Wie Sie sehen, hat jedes Sammlungsobjekt einen Iterator, mit Ausnahme Ihrer definierten Sammlungen, für die Sie Ihre eigenen Iteratoren definieren müssen.

Benutzer-Avatar
Brad

BEARBEITEN: Ich habe vergessen, das normale Array in meiner Antwort zu adressieren.

Bevor Sie dies alles lesen, wenn Sie neu in PHP sind und nicht versuchen, etwas Kniffliges zu tun, nur Werte zu speichern, die später verwendet werden sollen, dann verwenden Sie einfach den primitiven Array-Typ.

$data = [1,2,3,4,5];
//or
$data = array(1,2,3,4,5);

Array ist der Einstiegspunkt, und Sie sollten sich daran gewöhnen, sie zuerst zu verwenden, bevor Sie die Verwendung der anderen in Betracht ziehen. Wenn Sie Arrays nicht verstehen, werden Sie wahrscheinlich die Vorteile der Verwendung der anderen nicht verstehen. ( Sehen https://www.w3schools.com/php/php_arrays.asp für ein Tutorial zu Arrays. )

Ansonsten weiterlesen…

Ich habe die gleiche Frage und nachdem ich hierher gekommen war, entschied ich mich, einfach einige Zeit damit zu verbringen, sie auszuprobieren, und hier sind meine Ergebnisse und Schlussfolgerungen …

Lassen Sie uns zunächst einige Dinge klären, die von anderen gesagt wurden und die ich sofort getestet habe.

ArrayObject und ArrayItterator schützen die Daten nicht. Beide können weiterhin per Referenz in einer For-Each-Schleife übergeben werden (siehe zum Beispiel unten).

Beide geben true für is_object() zurück, beide geben false für is_array() zurück und beide ermöglichen den direkten Zugriff auf die Werte als Array, ohne einen Schutz für das Hinzufügen von Werten usw. zu bieten, und beide können per Referenz übergeben werden, sodass die ursprünglichen Daten während a manipuliert werden können für jede Schleife.

$array = new ArrayIterator();
var_dump(is_array($array)); // false
var_dump(is_object($array)); // true
$array[] = 'value one';
var_dump($array[0]);//string(9) "value one"

$array = new ArrayObject();
var_dump(is_array($array)); // false
var_dump(is_object($array)); // true
$array[] = 'value one';
var_dump($array[0]);//string(9) "value one"

Der große Unterschied ist in den Funktionen zu sehen, die für beide verfügbar sind.

ArrayIteroator verfügt über alle Funktionen, die zum Durchlaufen der Werte erforderlich sind, z. B. eine Foreach-Schleife. (Eine foreach-Schleife ruft die Methoden rewind(),valid(),current(),key() auf) siehe: https://www.php.net/manual/en/class.iterator.php für ein hervorragendes Beispiel des Konzepts (Dokumentation der Unterklasse).

Intellisense-Vorschläge der Pfeilfunktionen

Während ein ArrayObject immer noch iteriert werden kann und auf die gleiche Weise auf Werte zugreifen kann, bietet es keinen öffentlichen Zugriff auf Zeigerfunktionen.

Intellisense des Array-Objekts

Object ist so etwas wie das Hinzufügen eines Wrappers um das ArrayItterator-Objekt und hat public getIterator ( void ) : ArrayIterator das erleichtert das Durchlaufen der Werte im Inneren.

Sie können den ArrayItterator immer von ArrayObject erhalten, wenn Sie die hinzugefügten Funktionen wirklich benötigen.

ArrayItterator ist die beste Wahl, wenn Sie Ihre eigene Pseudo-Foreach-Schleife zum Durchqueren auf seltsame Weise haben und eine bessere Kontrolle wünschen, anstatt nur von Anfang bis Ende zu traversieren.

ArrayItterator wäre auch eine gute Wahl, um das Standardverhalten von Arrays zu überschreiben, wenn es von einer foreach-Schleife durchlaufen wird. z.B..

//I originally made to this to solve some problem where generic conversion to XML via a foreach loop was used,
//and I had a special case where a particular API wanted each value to have the same name in the XML.
class SameKey extends ArrayIterator{

    public function key()
    {
        return "AlwaysTheSameKey";
    }
}

$extendedArrayIterator =  new SameKey(['value one','value two','value three']);
$extendedArrayIterator[] = 'another item added after construct';
//according to foreach there all the keys are the same
foreach ($extendedArrayIterator as $key => $value){
    echo "$key: ";//key is always the same
    var_dump($value);
}
//can still be access as array with index's if you need to differentiate the values
for ($i = 0; $i < count($extendedArrayIterator); $i++){
    echo "Index [$i]: ";
    var_dump($extendedArrayIterator[$i]);
}

Das ArrayObject könnte eine gute Wahl sein, wenn Sie beispielsweise eine höhere Komplexität mit Itteratoren haben …

//lets pretend I have many custom classes extending ArrayIterator each with a different behavior..
$O = new ArrayObject(['val1','val2','val3']);
//and I want to change the behavior on the fly dynamically by changing the iterator class
if ($some_condition = true) $O->setIteratorClass(SameKey::class);
foreach ($O as $key => $value){
    echo "$key: ";//AlwaysTheSameKey:
    var_dump($value);
}

Ein Beispiel könnte die Änderung der Ausgabe desselben Datensatzes sein, z. B. eine Reihe benutzerdefinierter Iteratoren, die die Werte in einem anderen Format zurückgeben, wenn sie denselben Datensatz durchlaufen. z.B…

class AustralianDates extends ArrayIterator{
    public function current()
    {
        return Date('d/m/Y',parent::current());
    }
}
$O = new ArrayObject([time(),time()+37474,time()+37845678]);
//and I want to change the behaviour on the fly dynamically by changing the iterator class
if ($some_condition = true) $O->setIteratorClass(AustralianDates::class);
foreach ($O as $key => $value){
    echo "$key: ";//AlwaysTheSameKey:
    var_dump($value);
}

Offensichtlich gibt es wahrscheinlich bessere Möglichkeiten, so etwas zu tun.

Kurz gesagt, dies sind die wichtigsten Hauptvorteile, die ich sehen kann.

ArrayItorator – Fähigkeit auf niedrigerer Ebene, Traversalverhalten zu steuern oder zu erweitern und zu überschreiben.

VS

ArrayObject – ein Container für Daten, der jedoch die ArrayIterator-Klasse ändern kann.

Es gibt auch andere Unterschiede, die Sie vielleicht untersuchen möchten, aber ich denke, Sie werden sie nicht alle vollständig verstehen, bis Sie sie ausgiebig verwenden.

Es scheint, dass beide Objekte als Referenz in einem Foreach verwendet werden können, jedoch NICHT, wenn eine benutzerdefinierte Itterator-Klasse über ein ArrayObject verwendet wird.

//reference test
$I = new ArrayIterator(['mouse','tree','bike']);
foreach ($I as $key => &$value){
    $value="dog";
}
var_dump($I);//all values in the original are now 'dog'

$O = new ArrayObject(['mouse','tree','bike']);
foreach ($O as $key => &$value){
    $value="dog";
}
var_dump($O);//all values in the original are now 'dog'

$O->setIteratorClass(SameKey::class);
foreach ($O as $key => &$value){//PHP Fatal error:  An iterator cannot be used with foreach by reference
    $value="dog";
}
var_dump($O);

Empfehlung/Schlussfolgerung

Verwenden Sie Arrays.

Wenn Sie dann etwas Kniffliges tun möchten, würde ich empfehlen, immer ArrayIterator zu verwenden, um mit zu beginnen, und nur dann zu ArrayObject überzugehen, wenn Sie etwas Bestimmtes wollen, das nur ArrayObject kann.

In Anbetracht der Tatsache, dass das ArrayObject alle benutzerdefinierten ArrayIterators verwenden kann, die Sie auf dem Weg erstellt haben, würde ich sagen, dass dies der logische Weg ist.

Hoffe, das hilft dir so viel, wie es mir geholfen hat, es zu untersuchen.

  • Tut mir leid, ich habe vergessen, das Standardarray anzusprechen…. Wenn Sie nur eine Sammlung von Werten verwenden möchten/neu in PHP sind/nicht verstehen, was ich gesagt habe/keine besonderen kniffligen Dinge benötigen, dann verwenden Sie einfach einen Standard Reihe. Das Array ist, wo es beginnt, und Sie müssen sich daran gewöhnen, sie zu verwenden, bevor Sie den Rest verstehen.

    – Brad

    14. Mai 2019 um 4:01 Uhr


Ein Array in PHP ist eigentlich eine geordnete Karte. Eine Zuordnung ist ein Typ, der Schlüsseln Werte zuordnet. Dieser Typ ist für verschiedene Verwendungszwecke optimiert; Es kann als Array, Liste (Vektor), Hash-Tabelle (eine Implementierung einer Karte), Wörterbuch, Sammlung, Stapel, Warteschlange und wahrscheinlich mehr behandelt werden. Da Array-Werte andere Arrays sein können, sind auch Bäume und mehrdimensionale Arrays möglich.

Diese Klasse ermöglicht es Objekten, als Arrays zu arbeiten.

Dieser Iterator ermöglicht es, Werte und Schlüssel aufzuheben und zu ändern, während er über Arrays und Objekte iteriert.

Wenn Sie dasselbe Array mehrmals durchlaufen möchten, müssen Sie ArrayObject instanziieren und ArrayIterator-Instanzen erstellen lassen, die darauf verweisen, indem Sie entweder foreach verwenden oder seine Methode getIterator() manuell aufrufen.

  • Tut mir leid, ich habe vergessen, das Standardarray anzusprechen…. Wenn Sie nur eine Sammlung von Werten verwenden möchten/neu in PHP sind/nicht verstehen, was ich gesagt habe/keine besonderen kniffligen Dinge benötigen, dann verwenden Sie einfach einen Standard Reihe. Das Array ist, wo es beginnt, und Sie müssen sich daran gewöhnen, sie zu verwenden, bevor Sie den Rest verstehen.

    – Brad

    14. Mai 2019 um 4:01 Uhr


Benutzer-Avatar
Selten

Array ist array Typ, ArrayObject und ArrayIterator sind eingebaute Klassen mit ihren Instanzen object Typ, das teilweise sich verhalten wie Arrays auf Syntax- und Nutzungsebene.

Für die Klassen denke ich, dass die schnelle Idee aus den Schnittstellen gewonnen werden kann, die sie implementieren:

class ArrayObject implements IteratorAggregate, ArrayAccess, Serializable, Countable {
class ArrayIterator implements SeekableIterator, ArrayAccess, Serializable, Countable {

Beide Klassen implementieren:

  • ArrayAccesssodass sie die Array-Syntax für den Zugriff auf Werte unterstützen
  • Countablealso unterstützen sie die Anzahl der Werte, wie es Arrays tun
  • Iterator (wenn auch auf unterschiedliche Weise), also passen sie iterable Typ und kann mit überschleift werden foreach und derartige

Eine Möglichkeit, es zu betrachten, ist, dass Klassen viel Mühe haben, um zu arbeiten wie eine Anordnung. Der Punkt ist, dass sie als Klassen erweitert und angepasst werden können.

Sie wären auch von Natur aus interoperabel mit jedem Code, der erwartet Iterator Im Allgemeinen ist der grundlegende Anwendungsfall genau das – Wrapping, um Array-Daten in Iteratorcode einzuspeisen.

Also in aller Kürze ArrayObject und ArrayIterator sind Mach es selbst Arrays (mit einigen Implementierungsunterschieden zwischen den beiden). Ihre Instanzen verhalten sich (teilweise) wie array Typ, aber als Klassen sind sie erweiterbar und als Iterator Implementierer sind mit Code interoperabel, der dies möchte.

Außer du brauchen ein zutiefst angepasstes Verhalten und/oder Iterator Interoperabilität, Festhalten an array Typ ist wahrscheinlich der Weg zwischen diesen zu gehen.

Insbesondere gibt es auch Implementierungen von Sammlungen herum, die darauf abzielen, die Klassenvorteile mit freundlicheren Abstraktionen zu liefern.

1186340cookie-checkUnterschied zwischen ArrayIterator, ArrayObject und Array in PHP

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy