【问题标题】:PHP5: Objects referencePHP5:对象参考
【发布时间】:2015-07-12 03:40:00
【问题描述】:

我正在用 php 编写一些实体类,它们之间可能会指向一个存储库类(以避免使用本地实体存储库查询过多的数据库):

class Foo
{
    public $fooId;
    public $bar;
    function __construct($entity_id)
    {
        /**
        * Some Database stuff to get Foo object based on $entity_id
        **/
        $this->bar = Repository::get('Bar', $databaseStuff->barId);
    }
}

class Bar
{
    public $foo;
    function __construct($entity_id)
    {
        /**
        * Some Database stuff to get Bar object based on $entity_id
        **/
        $this->bar = Repository::get('Bar', $databaseStuff->barId);
    }
}

class Repository
{
    private static $entities = [];
    /**
     * @param string $entity_name
     * @param int $entity_id
     * @return mixed
     */
    public static function &get($entity_name, $entity_id)
    {
        $entity_name = ucfirst(strtolower($entity_name));
        if(!isset(self::$entities[$entity_name][$entity_id]))
        {
            self::$entities[$entity_name][$entity_id] =& $entity_name($entity_id);
        }
        return self::$entities[$entity_name][$entity_id];
    }
}

$foo = new Foo(1337);

问题是我得到一种超时/堆栈溢出可能是因为$foo->bar 是对 Bar 对象的引用,但 $bar->foo 是对 Foo 的引用对象等...

  • 我没有忘记使用 &get() 声明我的函数以返回引用,对吗?
  • 我的类是用 =& 运算符实例化的。

我的代码(或我的逻辑)可能有什么问题? 谢谢。

【问题讨论】:

  • 我从未见过函数引用..
  • PHP 不能很好地处理循环引用,并且已知某些事情会导致问题。例如,如果您尝试serialize(),它将无限期地产生输出,直到它耗尽内存或时间。垃圾收集器(或者至少我认为是 gc 导致的)也会有一些令人讨厌的性能问题和最终的崩溃。我最近在这方面有很多经验,并决定最好避免在 PHP 中进行循环引用。
  • 这样怎么处理?就我而言,我有一个“用户”类和一个“资产”类。用户有头像(即资产对象),资产有用户(即用户对象)。
  • 另外,据我所知,您在任何时候都不会打电话给get()。你应该打电话给&Repository::get() 而不仅仅是Repository()。返回引用的函数也必须使用& 调用才能工作。但是,如果您要返回一个对象,则可以删除整个引用事物。对象已经通过引用隐式传递。要在 PHP 中传递对象的副本,您必须使用 clone $object 明确地说出来。
  • 这是一个糟糕的复制/粘贴,我正在有效地调用 Repository::get()

标签: php oop reference circular-reference


【解决方案1】:

如果我没看错,Bar 的构造函数会尝试创建新的 Bar。
我想这样的嵌套结构永远不会结束。它是一样的,例如当函数以递归方式调用自身而无法退出时。
该脚本甚至不会写入存储库。

曾经尝试过 xdebug 吗?这可以很快显示问题。

顺便说一句,复制/粘贴可能会出错。 Foo 类中的注释与它所在的行不匹配。你在类 Bar 中设置 $this->bar,但只声明了类变量 $foo。

【讨论】:

  • 是的,这是一个糟糕的复制/粘贴,不,我从未尝试过 xdebug,可能是因为它配置起来太复杂了。
猜你喜欢
  • 1970-01-01
  • 2016-01-09
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
相关资源
最近更新 更多