用 php 找出变量是否是这个确切的类实例


With php finding out if variable is this exact class instance

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

抽象类(其部分如下所示)具有一个方法 fetch_mother(),旨在标识应包含它的对象并返回该对象,或者只是返回自身,因为它位于堆栈的底部。理论上,该堆栈不应超过 5 深。

大多数实例表示类别之类的内容。

使用 get get_full_path() 方法:

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

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

这意味着健全性检查启动并打破循环。这也意味着我没有正确测试返回的对象与$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)也是真的。但是,如果创建了具有相同属性的另一个对象,则上述对象将为 false,因为它们是单独的对象。

这个问题和答案涉及完全相同的主题:spl_object_hash匹配,对象不相同

的问题中的假设(我一开始没有看到)是查找函数充当工厂和缓存对象。差异结论必须是返回副本或第二个实例。

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

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

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

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

这种特殊的解决方案是丑陋的,不优雅的,也不是很可靠。

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

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