首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP语言中ArrayIterator、ArrayObject和数组的区别

PHP语言中ArrayIterator、ArrayObject和数组的区别
EN

Stack Overflow用户
提问于 2012-05-09 00:37:53
回答 7查看 20.4K关注 0票数 32

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

EN

回答 7

Stack Overflow用户

发布于 2014-06-15 06:01:03

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

ArrayObject是一种object,它的工作方式与数组完全相同。可以使用new关键字创建这些文件

ArrayIterator类似于ArrayObject,但它可以在自身上迭代。还使用new创建

Array (**ArrayObject**/**ArrayIterator**)的比较

它们都可以使用php的数组语法来使用,例如。

代码语言:javascript
复制
$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

但是,它们仍然是对象和数组,所以您会注意到

代码语言:javascript
复制
is_array($array); // true
is_array($object); // false

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

大多数php数组函数都需要数组,所以在数组中使用对象会抛出错误。这样的函数有很多。例如。

代码语言:javascript
复制
sort($array); // works as expected
sort($object); // Warning: sort() expects parameter 1 to be array, object given in ......

最后,对象可以执行您期望从stdClass对象执行的操作,即使用对象语法访问公共属性

代码语言:javascript
复制
$object->foo = 'bar'; // works
$array->foo = 'bar'; // Warning: Attempt to assign property of non-object in ....

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

ArrayIterator进行比较

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

ArrayIterator实现了Iterator接口,该接口为其提供了与元素迭代/循环相关的方法。ArrayObject有一个名为exchangeArray的方法,可以将它的内部数组与另一个内部数组交换。在ArrayIterator中实现类似的操作意味着要么创建一个新对象,要么循环遍历所有键&一个接一个地对所有键执行unset操作,然后从新数组中逐个设置元素。

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

票数 33
EN

Stack Overflow用户

发布于 2014-12-20 18:50:43

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

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

你有一个拥有数组的类。您可以使用addSomethingToMyArray将项添加到该数组。但是请注意,我们在将item添加到数组之前对它做了一些操作。这可以是任何东西,但让我们暂时表现一下,对于我们想要添加到数组中的每一项,这个方法都会被触发,这一点非常重要。

代码语言:javascript
复制
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中的数组。但是我们需要doSOmethingToItem,记得吗?这是一个无法控制自身内部状态的类的例子。

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

代码语言:javascript
复制
<?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;
    }       
}

?>

正如您所看到的,我无法将新项添加到给定的数组中,但我确实可以像这样读取数组:

代码语言:javascript
复制
while( $iterator->hasNext() )
    $item = $iterator->next();

现在,只有一种方法可以将项添加到A中的myArray,即通过addSomethingToArray方法。这就是迭代器,它在某种程度上是数组周围的外壳,以提供称为封装的东西。

票数 10
EN

Stack Overflow用户

发布于 2012-05-09 00:47:38

  • Arrays

中的数组实际上是一个有序的映射。映射是一种将值与键相关联的类型。该类型针对几种不同的用途进行了优化;可以将其视为数组、列表(向量)、哈希表(映射的实现)、字典、集合、堆栈、队列等等。由于数组值可以是其他数组,因此树和多维数组也是可能的。

  • The ArrayObject class

这个类允许对象像数组一样工作。

  • The ArrayIterator class

此迭代器允许在迭代数组和对象时取消设置和修改值和键。

当您希望多次迭代同一数组时,需要实例化ArrayObject,并让它创建引用它的ArrayIterator实例,方法是使用foreach或手动调用它的getIterator()方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10502719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档