機能と操作の観点からArrayIterator
、ArrayObject
とPHPの基本的な違いを誰かが明確に説明できますか? Array
ありがとう!
7 に答える
Array
ネイティブphpタイプです。php 言語構造を使用してarray()
、または php 5.4 以降で作成できます。[]
ArrayObject
object
配列とまったく同じように機能する です。new
これらはキーワードを使用して作成できます
ArrayIterator
に似ArrayObject
ていますが、それ自体を繰り返すことができます。こちらも作成new
Array
対 ( ArrayObject
/ ArrayIterator
)の比較
どちらも php の配列構文を使用して使用できます。
$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
ただし、それらは依然としてオブジェクトと配列であるため、違いに気付くでしょう。
is_array($array); // true
is_array($object); // false
is_object($array); // false
is_object($object); // true
ほとんどの PHP 配列関数は配列を想定しているため、そこでオブジェクトを使用するとエラーがスローされます。そのような機能はたくさんあります。たとえば。
sort($array); // works as expected
sort($object); // Warning: sort() expects parameter 1 to be array, object given in ......
最後に、オブジェクトはオブジェクトに期待されることを実行できstdClass
ます。つまり、オブジェクト構文を使用してパブリック プロパティにアクセスできます。
$object->foo = 'bar'; // works
$array->foo = 'bar'; // Warning: Attempt to assign property of non-object in ....
配列 (ネイティブ型) は、オブジェクトよりもはるかに高速です。一方、ArrayObject
&ArrayIterator
クラスには、使用できる特定のメソッドが定義されていますが、配列にはそのようなものはありません
比較ArrayObject
するArrayIterator
これら 2 つの主な違いは、クラスが持つメソッドにあります。
要素の繰り返し/ループに関連するメソッドを提供するインターフェイスをArrayIterator
実装します。内部配列を別の配列と交換するというメソッドがあります。同様のことを実装することは、新しいオブジェクトを作成するか、キーをループしてそれらすべてを 1 つずつ ing してから、新しい配列の要素を 1 つずつ設定することを意味します。Iterator
ArrayObject
exchangeArray
ArrayIterator
unset
次に、 はArrayObject
反復できないため、使用すると内部foreach
でオブジェクトが作成ArrayIterator
されます (配列と同じ)。これは、php が元のデータのコピーを作成し、同じ内容のオブジェクトが 2 つあることを意味します。これは、大規模な配列では非効率的であることがわかります。ただし、反復子に使用するクラスを指定できるため、コードにカスタム反復子を含めることができます。
ArrayObject と配列は多少似ています。オブジェクト (またはネイティブ型) の単なるコレクションです。呼び出すことができるいくつかの異なるメソッドがありますが、ほとんど同じことになります。
ただし、Iterator はまったく別のものです。イテレータ デザイン パターンは、配列を保護する (読み取りのみ可能にする) 方法です。次の例を見てみましょう。
配列を持つクラスがあります。addSomethingToMyArray を使用して、その配列に項目を追加できます。ただし、アイテムを実際に配列に追加する前に、アイテムに何かを行うことに注意してください。これは何でもかまいませんが、配列に追加したいすべての項目に対してこのメソッドが起動されることが非常に重要であるように、少しの間考えてみましょう。
class A
{
private $myArray;
public function returnMyArray()
{
return $this->myArray;
}
public function addSomethingToMyArray( $item )
{
$this->doSomethingToItem( $item );
array_push( $item );
}
}
これに関する問題は、ここで参照によって配列を渡すことです。つまり、実際に returnMyArray を使用するクラスは実際の myArray オブジェクトを取得します。つまり、A 以外のクラスはその配列に何かを追加できるため、addSOmethingToMyArray を使用せずに A 内の配列も変更できます。しかし、SOmethingToItem を実行する必要があったことを覚えていますか? これは、自身の内部ステータスを制御できないクラスの例です。
これに対する解決策は反復子です。配列を渡す代わりに、配列からの読み取りのみが可能な新しいオブジェクトに配列を渡します。これまでで最も単純な Iterator は次のようなものです。
<?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;
}
}
?>
ご覧のとおり、指定された配列に新しい項目を追加する方法はありませんが、次のように配列を読み取る可能性はあります。
while( $iterator->hasNext() )
$item = $iterator->next();
ここでも、A の myArray に項目を追加する方法は 1 つしかありません。つまり、addSomethingToArray メソッドを使用する方法です。それがイテレータであり、カプセル化と呼ばれるものを提供するために、配列の周りのシェルのようなものです。
PHP の配列は、実際には順序付きマップです。マップは、値をキーに関連付けるタイプです。このタイプは、いくつかの異なる用途に最適化されています。配列、リスト (ベクトル)、ハッシュ テーブル (マップの実装)、辞書、コレクション、スタック、キューなどとして扱うことができます。配列値は他の配列にすることができるので、ツリーや多次元配列も可能です。
このクラスにより、オブジェクトを配列として機能させることができます。
この反復子を使用すると、配列とオブジェクトを反復処理しながら、値とキーを設定解除および変更できます。
同じ配列を複数回反復処理する場合は、ArrayObject をインスタンス化し、foreach を使用するか、その getIterator() メソッドを手動で呼び出して、それを参照する ArrayIterator インスタンスを作成できるようにする必要があります。