php 找出变量是否是这个 class 实例

With php finding out if variable is this exact class instance

我 运行 在弄清楚如何比较两个可能包含完全相同的 class 实例的变量时遇到了麻烦。

一个抽象 class(下面显示了其中的一部分)有一个方法 fetch_mother() 旨在识别应该包含它的对象和 return 或简单地 return 本身,因为它位于堆栈的底部。理论上,该堆栈不应超过 5 层。

大多数实例代表类别之类的东西。

使用 get get_full_path() 方法:

预期输出为:[siteurl] /system/drafts/example-one/also-dev-notes/

实际输出为:[siteurl] /drafts/drafts/[snip]/drafts/drafts/example-one/also-dev-notes/

这意味着健全性检查开始并打破循环。这也意味着我没有正确测试 returned 对象是否与 $this.

相同

如何确认是 $var===$this

问题发生代码:

<?php
namespace modules\content\classes;
use modules\core\interfaces as i;
use modules\core\classes as c;

abstract class content_object extends c\module_lib {

    // vars
    // ...
    protected $mother;
    protected $map

    // ... code ...

    public function get_object_map(){
        return $this->map;
    }

    /**
     * Get the stream holding this item
     * @return \modules\content\classes\error|\modules\content\classes\content_object 
     */
    public function &fetch_mother(){
        if(isset($this->mother) && is_object($this->mother)){
            return $this->mother;
        }
        $mother = $this->module()->find_object_stream($this);
        if(!($mother instanceof \modules\core\error) && is_object($mother) && $mother != $this){
            $this->mother = $mother;
            return $mother;
        }else{
            // I am my own mother ? \
            return $this;
        }
    }

    protected function fetch_full_path_from_mother($path='',$sanity=10){
        $map = $this->get_object_map();
        $mother = $this->fetch_mother();
        $path = $map . '/' . $path;
        if($this==$mother || !is_object($mother) || $sanity<1){
            return $path;
        }
        $sanity--;
        return $mother->fetch_full_path_from_mother($path,$sanity);
    }

    public function get_full_path(){
        $home = $this->get_core()->factory()->get_config('home');
        return $home . $this->fetch_full_path_from_mother();
    }
}

这里的答案并不明显。

<?php
$foo = $this;
if($foo==$this){
    echo 'It is';
}else{
    echo 'It is not';
}

上面的输出将是 It is

那是因为如果两个对象是同一个实例,那么 == 比较就足以确定这一点。

同样(根据评论)spl_object_hash($mother)==spl_object_hash($this)也是正确的如果它是同一个对象。但是,如果创建了另一个具有相同属性的对象,则上述内容将是错误的,因为它们是单独的对象。

这个问题和答案涉及完全相同的主题:spl_object_hash matches, objects not identical

我的问题中的假设(我起初没有看到)是查找函数充当工厂和缓存对象。差分结论一定是返还副本或二审。

因此,问题一定出在fetch_mother()方法上。

(进一步调查确实表明这是问题所在。)

解决方案包括检查匹配的属性(在这种情况下可以工作,因为有几个从数据库中提取的唯一字段)或比较 print_r 输出。

if(print_r($mother,true)==print_r($this,true)){
    // code
}

那个特定的解决方案丑陋、不优雅且不太可靠。

更好的解决方案是在堆栈的较高位置实现对象缓存。 (这就是我要提议的)。

TL;DR: 具有相同属性的对象仍然不相同。