PHP: 如何"clone from" 另一个相同class 的对象? 'Internally clone' 来自源对象的当前对象,不从当前对象克隆另一个对象

PHP: how to "clone from" another object of same class? 'Internally clone' current object from source obj, NOT clone another object from current

在我当前的应用程序中,我有一些重复需要的对象

为了节省反复实例化同一个对象的开销,我保留了一个 'known' 个对象的数组。
我可以根据数组检查输入数据,并且 - 如果已经设置 - 使用现有对象,否则继续实例化新对象并将指针引用添加到相关的已知对象数组。

在大多数情况下,我可以在实例化 class:

之前进行检查
if(array_key_exists($identifier,$known_ClassObjects)){
   $object = $known_ClassObjects[$identifier];
} else {
   $object = new Class($params);
}

但是,在某些情况下,我只能确定我正在实例化的对象已经存在于其中。

在那种情况下,我希望能够做以下两件事之一:

  1. return 其他(预先存在的)对象 而不是这个,例如
class Test{

    public function __construct($params){
        
        //apply processing to $params, resulting in $identifier 

        if(array_key_exists($identifier, $known_ClassObjects)){ //$known_ClassObjects is global

             return $known_ClassObjects[$identifier];

        } else {

             //continue __construct() logic

             return $this;
        }

    }
}

但是,PHP 总是 return 是当前对象,即使使用代码 return $other_object;

  1. 'Internally Clone'当前对象从找到的一个[相同class,obv]所以当它returns,它填充了正确的相关属性。

注意:包括任何 parent/child class 属性 -> 我想让这个对象与找到的对象完全一样。

所以,如果有一个 PHP 函数 clone_from(),它会像这样工作:

if(array_key_exists($identifier,$known_ClassObjects)){
   $this->clone_from ($known_ClassObjects[$identifier]);

} else {
   //continue with __construct()

}
return $this;

鉴于 1. 不起作用且 2. 似乎不存在,我只能以非常 'hacky' 的方式做到这一点:遍历源对象的所有属性并设置所有当前对象的属性。

但是,这有明显的问题,尤其是。扩展 parent/child classes 等,然后需要反射 classes.

这似乎应该有一个非常简单的解决方案,但我一直找不到一个

However, PHP ALWAYS returns the current object, even with code return $other_object;

构造函数不是常规函数。你不return从它。如果您在 __construct() 中,则您已经在构建新对象。在继续之前,我强烈建议您至少阅读:https://www.php.net/manual/en/language.oop5.decon.php

您很可能需要一个辅助方法或工厂来处理它。将您试图放入构造函数的逻辑是错误的。

您还没有澄清 $identifier 的真正含义。但是,如果那是对象的 属性,那么您可以公开它(即通过 getter)并让其他代码为您的 comparison/whatever 读取它。

您实际上可以做的是使用单例模式或工厂模式 - 在这两种情况下,对象的创建都由一些代码控制,您可以决定,反对 return。单例已经是工厂模式的一种特殊形式。

考虑这段代码

class Singleton {
    protected static $instance; 
    
    protected function __construct() { 
    }
    
    public static function instance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
} 

构造函数是 protected,它将阻止通过 new 从“外部”构造对象。但是,还有一个静态函数 instance,有人可以使用它 请求 来自工厂方法的对象实例。

$obj = Singleton::instance(); 

因此,(内部)对象只创建一次,然后在脚本结束之前交付。