如何从其他PHP对象复制值来创建新实例

如何从其他PHP对象复制值来创建新实例,php,Php,对于一个计量项目,我有一个MeterReadings类,它的构造函数将以前的读数作为其所有属性值(时间戳除外)的基础。在本例中,对象只有3个属性,在现实生活中还有更多属性。我可以一行一行地为每个财产做X $this->propertyX=$prevMS->propertyX 但这很快就会变得乏味 从$prevMS对象复制所有属性值的最佳做法是什么 <?php class MeterReadings{ function __construct($prevMS=NULL)

对于一个计量项目,我有一个MeterReadings类,它的构造函数将以前的读数作为其所有属性值(时间戳除外)的基础。在本例中,对象只有3个属性,在现实生活中还有更多属性。我可以一行一行地为每个财产做X

$this->propertyX=$prevMS->propertyX
但这很快就会变得乏味

$prevMS
对象复制所有属性值的最佳做法是什么

<?php class MeterReadings{
    function __construct($prevMS=NULL){
        if($prevMS===NULL){
            $this->gas=0;
            $this->water=0;
            $this->electricity=0;
        }else{
          //PHP can duplicate an object by assignment,
          //so I expected to be able to create a copy of $prevMS 
          //but cannot $this=$prevMS;
          //and cannot $this= clone $that;
          //which both throw error 'Cannot re-assign $this'
          foreach($prevMS as $key => $value){
            //logs "Undefined property: MeterReadings::$0"  
            print "$key => $value\n";   
            $this->$key = $prevMS->$value;
          }
        }
        $this->date=time();//set timestamp for this object
    }
}
$test= new MeterReadings();
$test2 = new MeterReadings($test);
print_r($test);
print_r($test2);
?>gets me

gas => 0
water => 0
electricity => 0
date => 1434448706
MeterReadings Object
 (
    [gas] => 0
    [water] => 0
    [electricity] => 0
    [date] => 1434448706
)
MeterReadings Object
(
    [gas] => 
    [water] => 
    [electricity] => 
    [date] => 1434448706
)
抓住我了
气体=>0
水=>0
电力=>0
日期=>143448706
MeterReadings对象
(
[气体]=>0
[水]=>0
[电]=>0
[日期]=>143448706
)
MeterReadings对象
(
[气体]=>
[水]=>
[电力]=>
[日期]=>143448706
)

您可以使用
克隆
\u克隆
来管理要克隆的内容

例如:

class Test
{
    public $value1;
    public $value2;
    public $timestamp;

    public function __clone()
    {
        $this->timestamp = null;
    }
}

$test = new Test();
$test->value1 = 1;
$test->value2 = 2;
$test->timestamp = time();

$test2 = clone $test;

print_r($test2);

// Test Object
// (
//     [value1] => 1
//     [value2] => 2
//     [timestamp] => 
// )
备选方案:

如需保持
\uuu construct
中规定的内容,请在下面的注释中注明:

class Test
{
    public $value1;
    public $value2;
    public $timestamp;

    public function __construct (Test $copy = null)
    {
        if($copy) {
            foreach ($copy as $key => $value) {
                $this->$key = $value;
            }
        }
        $this->timestamp = 'whoop';
    }
}

$test = new Test();
$test->value1 = 1;
$test->value2 = 2;
$test->timestamp = 'whatev\'s';

$test2 = new Test($test);

print_r($test2);

// Test Object
// (
//     [value1] => 1
//     [value2] => 2
//     [timestamp] => 'whoop'
// )

这将适用于不可写入的对象和受保护(但非私有)的属性。对于可写入并返回其他内容的对象,可以使用
get\u object\u vars()
。对于私有的东西(你确定你需要私有的,这是不寻常的),你需要创建getter。如果您不希望它们在外部可用,则可以对其进行保护。

DanielM,感谢您使用此神奇方法。我试图将所有内容都保存在_构造方法中,但是
$this=clone($prevMS)是不允许的。我们希望所有的价值观都对班级保密。我将这个问题调整为这个目的。PHP中的对象存储为引用。即使可以执行
$this=$object
,也必须引用同一个对象。作为替代方法,您可以执行
foreach($key=>object$value){$this->$key=$value;}
。该对象不需要是可写入的,就可以工作。如果对象是可写入的,则可以使用
get\u object\u vars()
谢谢。我们同时编辑了问答。我明白我的错误;不应该提及
$prevMS->$value
,而应该仅提及
$value
。我想你的意思是“你会有两个参考资料”。它正在工作,非常感谢!是的。我真的很讨厌在点击提交之前没有阅读我的帖子p正因为这个原因,我可能是重复编辑中排名前5%的人P