复制PHP类的实例,同时保留基类中的数据


Copying an instance of a PHP class while preserving the data in a base class?

我有以下三个类:

class a
{ public $test; }
class b extends a { }
class c extends a
{
    function return_instance_of_b() { }
}

可以看出,bc都是从a派生出来的。在creturn_instance_of_b()函数中,我想返回类b的实例。基本上是return new b();,有一个额外的限制:

我需要将来自基类(a)的数据复制到返回的b实例中。我该怎么做呢?也许是clone关键字的变体?

您可以使用get_class_vars函数来检索您想要复制的变量的名称,并只是循环复制它们。

定义的变量是受保护的,因此它们对get_class_vars在其作用域内可见(因为c扩展了a),但不能直接在类外访问。您可以将它们更改为public,但是private将隐藏get_class_vars中的这些变量。

<?php
class a
{ 
    protected $var1;
    protected $var2;
}
class b extends a 
{
}
class c extends a
{
    function __construct()
    {
        $this->var1 = "Test";
        $this->var2 = "Data";
    }
    function return_instance_of_b() 
    {
        $b = new b();
        // Note: get_class_vars is scope-dependant - It will not return variables not visible in the current scope
        foreach( get_class_vars( 'a') as $name => $value) {
            $b->$name = $this->$name;
        }
        return $b;
    }
}
$c = new c();
$b = $c->return_instance_of_b();
var_dump( $b); // $b->var1 = "Test", $b->var2 = "Data

我相信您可以通过一些反思来实现这一点。不是很漂亮的代码,我相信有一个更简洁的方法来实现这一点,但你在这里。

class a
{ 
    public $foo;
    public $bar;
    function set($key, $value) {
        $this->$key = $value;
    }
    function get($key) {
        return $this->$key;
    }
}
class b extends a 
{ 
    function hello() {
        printf('%s | %s', $this->foo, $this->bar);
    }
}
class c extends a
{   
    public $ignored;
    function return_instance_of_b() {
    $b = new b();
    $reflection = new ReflectionClass($this);
    $parent = $reflection->getParentClass();
    foreach($parent->getProperties() as $property) {
        $key = $property->getName();
        $value = $property->getValue($this);
        $b->$key = $value;
    }
    return $b;
    }
}
$c = new c();
$c->set('foo', 'bar');
$c->set('bar', 'bar2');
$c->set('ignored', 'should be!');
$b = $c->return_instance_of_b();
$b->hello();
// outputs bar | bar2

另外,你可以使用nickb的答案,但不是硬编码类,你可以使用get_parent_class

function return_instance_of_b() 
    {
        $b = new b();
        foreach(get_class_vars(get_parent_class(__CLASS__)) as $name => $value) {
            $b->$name = $this->$name;
        }
        return $b;
    }