如何在PHP中创建对象的副本?

ncgqoxb0  于 2023-01-16  发布在  PHP
关注(0)|答案(9)|浏览(126)

在PHP中,对象似乎是通过引用传递的,甚至赋值操作符似乎也没有创建对象的副本。
这里有一个简单的、人为的证明:

<?php

class A {
    public $b;
}

function set_b($obj) { $obj->b = "after"; }

$a = new A();
$a->b = "before";
$c = $a; //i would especially expect this to create a copy.

set_b($a);

print $a->b; //i would expect this to show 'before'
print $c->b; //i would ESPECIALLY expect this to show 'before'

?>

在两种打印情况下,我都得到了“之后”
那么,如何通过值而不是通过引用将**$a传递给*set_B()***呢?

wgmfuz8q

wgmfuz8q1#

在PHP 5+中,对象是通过引用传递的。在PHP 4中,对象是通过值传递的(这就是为什么它有运行时通过引用传递,这已经过时了)。
你可以使用PHP5中的'clone'操作符来复制对象:

$objectB = clone $objectA;

而且,它只是通过引用传递的对象,而不是您在问题中所说的所有内容...

wb1gzix0

wb1gzix02#

答案通常可以在Java书籍中找到。

  1. cloning:如果你不重写clone方法,默认行为是浅复制。2如果你的对象只有原始成员变量,这完全没问题。3但是在一个无类型语言中,如果有另一个对象作为成员变量,这就很麻烦了。
    1.串行化/反串行化
    $new_object = unserialize(serialize($your_object))
    这以取决于对象的复杂性的高成本来实现深度复制。
fdbelqdn

fdbelqdn3#

根据前面的注解,如果您有另一个对象作为成员变量,请执行以下操作:

class MyClass {
  private $someObject;

  public function __construct() {
    $this->someObject = new SomeClass();
  }

  public function __clone() {
    $this->someObject = clone $this->someObject;
  }

}

现在您可以执行克隆:

$bar = new MyClass();
$foo = clone $bar;
a5g8bdjr

a5g8bdjr5#

只是为了澄清PHP使用写时复制,所以基本上所有的东西都是引用,直到你修改它,但是对于对象你需要使用clone和__clone()魔术方法,就像在接受的答案。

z2acfund

z2acfund6#

此代码有助于克隆方法

class Foo{

    private $run=10;
    public $foo=array(2,array(2,8));
    public function hoo(){return 5;}

    public function __clone(){

        $this->boo=function(){$this->hoo();};

    }
}
$obj=new Foo;

$news=  clone $obj;
var_dump($news->hoo());
zrfyljdw

zrfyljdw7#

我做了些测试然后得到了这个:

class A {
  public $property;
}

function set_property($obj) {
  $obj->property = "after";
  var_dump($obj);
}

$a = new A();
$a->property = "before";

// Creates a new Object from $a. Like "new A();"
$b = new $a;
// Makes a Copy of var $a, not referenced.
$c = clone $a;

set_property($a);
// object(A)#1 (1) { ["property"]=> string(5) "after" }

var_dump($a); // Because function set_property get by reference
// object(A)#1 (1) { ["property"]=> string(5) "after" }
var_dump($b);
// object(A)#2 (1) { ["property"]=> NULL }
var_dump($c);
// object(A)#3 (1) { ["property"]=> string(6) "before" }

// Now creates a new obj A and passes to the function by clone (will copied)
$d = new A();
$d->property = "before";

set_property(clone $d); // A new variable was created from $d, and not made a reference
// object(A)#5 (1) { ["property"]=> string(5) "after" }

var_dump($d);
// object(A)#4 (1) { ["property"]=> string(6) "before" }

?>
tvokkenx

tvokkenx8#

在本例中,我们将创建iPhone类,并通过克隆从该类创建精确副本

class iPhone
{
    public $name;
    public $email;

    public function __construct($n, $e) {

       $this->name = $n;
       $this->email = $e;

    }
}

$main = new iPhone('Dark', 'm@m.com');
$copy = clone $main;

// if you want to print both objects, just write this    

echo "<pre>"; print_r($main);  echo "</pre>";
echo "<pre>"; print_r($copy);  echo "</pre>";
efzxgjgh

efzxgjgh9#

如果要完全复制不同示例中对象的特性,可能需要使用以下方法:
将其序列化为JSON,然后反序列化回Object。

相关问题