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

时间:2011-09-22 05:32:50

标签: php class clone instance

我有以下三个类:

class a
{ public $test; }

class b extends a { }
class c extends a
{
    function return_instance_of_b() { }
}

如您所见,bc这两个类派生自a。在return_instance_of_b()中的c函数中,我想返回类b的实例。基本上return new b();有一个额外的限制:

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

2 个答案:

答案 0 :(得分:2)

您可以使用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

答案 1 :(得分:0)

我相信你可以通过一些反思实现这一目标。不是很漂亮的代码,我敢肯定有更简洁的方法来实现这个目标,但是你走了。

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;
    }