in_array与循环引用的对象 [英] in_array on objects with circular references

查看:176
本文介绍了in_array与循环引用的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立对象的数组。我需要这个数组只包含一次给定对象的实例,其应该抛出一个异常同一对象多个引用。我用下面的code来实现这一点:

I'm building an array of objects. I need this array to only contain once instance of a given object, having multiple references to the same object should throw an exception. I'm using the following code to achieve this:

public function addField ($name, iface\Node $field)
{
    // Prevent the same field being added multiple times
    if (!in_array ($field, $this -> fields))
    {
        $this -> fields [$name] = $field;
        $field -> setParent ($this);
    }
    else
    {
        throw new \InvalidArgumentException ('This field cannot be added to this group');
    }
    return ($this);
}

这开始导致问题,当我开始实施实现Node接口,因为它们可以包括循环引用的对象(他们拥有自己的子节点的集合,每个孩子拿着其父的引用)。尝试添加一个字段可导致下面的错误而产生

This started leading to problems when I started implementing the objects that implement the Node interface, as they can include circular references (they hold a collection of their child nodes, with each child holding a reference to its parent). Trying to add a field can result in the following error being generated:

PHP致命错误:嵌套级别太深 - 递归依赖性

PHP Fatal error: Nesting level too deep - recursive dependency?

我怀疑PHP试图遍历整个对象数组,而不是仅仅比较对象引用,看看他们是否持有相同的值,从而指向同一个对象。

I suspect that PHP is trying to traverse the entire object array, rather than just comparing the object references to see if they hold the same value and therefore point to the same object.

我需要什么in_array要做的只是比较它与现场的对象引用存储对象的引用。这将prevent它试图遍历整个对象树和跑入递归问题。

What I need in_array to do is just compare the object references it stores with the object reference of field. This would prevent it trying to traverse the whole object tree and running into the recursion problem.

是否有这样做的一种方式?

Is there a way of doing this?

推荐答案

原来答案是extraordinarally简单。这样看来,在默认情况下in_array测试对于针草堆时确实非严格比较(相当于==操作)。这意味着,它会检查所有属性都是平等的,这意味着它开始遍历对象图,并可以给你带来麻烦,如果你有在图形循环引用。

Turns out the answer is extraordinarally simple. It would appear that by default in_array does non-strict comparison (equivalent to an == operation) when testing the haystack for the needle. This means that it checks that all the properties are equal, which means it starts traversing the object graph, and that can get you into trouble if you have circular references in that graph.

该in_array功能有着严格的模式,然而,据我可以告诉做一个===操作的等价物。这似乎导致其检查的引用,看他们是否指向同一对象,而不是比较所有属性。

The in_array function has a strict mode, however, which as far as I can tell does the equivalent of an === operation. This seems to cause it to check the references to see if they point at the same object instead of comparing all the properties.

只要改变code为:

if (!in_array ($field, $this -> fields, true))

使得表现得像我想它没有它触发递归错误的行为方式。

makes the method behave as I wanted it to behave without it triggering the recursion error.

我不得不说,我有点惊讶的是PHP默认情况下不执行此操作模式。在另一方面,我想我真的不该感到惊讶,PHP的弱类型再次引起了我的问题。 :)

I have to say that I'm a little surprised that PHP doesn't do this mode by default. On the other hand I guess I really ought not to be surprised that PHP's weak typing has caused me an issue again. :)

这篇关于in_array与循环引用的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆