PHP 中 ArrayIterator、ArrayObject 和 Array 之间的区别

2022-08-30 13:58:39

有人能清楚地解释PHP和PHP在功能和操作方面的根本区别吗?谢谢!ArrayIteratorArrayObjectArray


答案 1

Array是一种原生的 php 类型。您可以使用 php 语言构造创建一个,或者从 php 5.4 开始array()[]

ArrayObject是一个与数组完全相同的工作方式。这些可以使用关键字创建objectnew

ArrayIterator就像,但它可以自我迭代。也是使用ArrayObjectnew


比较数组与(数组对象/数组迭代器

它们都可以使用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 ....

数组(作为本机类型)比对象快得多。另一方面,&类定义了某些可以使用的方法,而数组没有这样的东西ArrayObjectArrayIterator


比较数组对象数组迭代器

这两者之间的主要区别在于类具有的方法。

实现接口,它为它提供了与元素迭代/循环相关的方法。 有一个名为的方法,该方法将其内部数组与另一个数组交换。在 中实现类似的东西意味着要么创建一个新对象,要么循环通过键并逐个遍历所有键,然后逐个设置新数组中的元素。ArrayIteratorIteratorArrayObjectexchangeArrayArrayIteratorunset

接下来,由于无法迭代,因此当您在其中使用它时,会在内部创建一个对象(与数组相同)。这意味着php创建了原始数据的副本,现在有2个具有相同内容的对象。对于大型阵列来说,这将被证明是低效的。但是,您可以指定要用于迭代器的类,以便可以在代码中使用自定义迭代器。ArrayObjectforeachArrayIterator


答案 2

数组对象和数组有点相似。仅仅是对象(或本机类型)的集合。他们有一些不同的方法,你可以调用,但它主要归结为同样的事情。

但是,迭代器完全是另一回事。迭代器设计模式是保护数组(使其仅可读)的一种方法。让我们举下一个例子:

您有一个具有数组的类。您可以使用 addSomethingToMyArray 向该数组添加项。但请注意,在实际将其添加到数组之前,我们会对 item 执行一些操作。这可以是任何东西,但让我们暂时表现得好像为我们要添加到数组中的每个项目触发此方法非常重要。

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

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

这样做的问题是,您在此处通过引用传递数组。这意味着实际使用 returnMyArray 的类将获得真正的 myArray 对象。这意味着 A 以外的类可以向该数组添加内容,因此还可以更改 A 中的数组,而无需使用 addSOmethingToMyArray。但是我们需要做SOmethingToItem,还记得吗?这是一个类无法控制其自身内部状态的示例。

解决此问题的方法是迭代器。我们不是传递数组,而是将数组传递给一个新对象,该对象只能从数组中读取内容。最简单的迭代器是这样的:

<?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,即通过addSomethingToArray方法。这就是迭代器,它有点像数组周围的外壳,以提供一种叫做封装的东西。