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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/185934/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 21:50:13  来源:igfitidea点击:

How do I create a copy of an object in PHP?

phpcopycloneshallow-copy

提问by Nick Stinemates

It appears that in PHP objects are passed by reference. Even assignment operators do not appear to be creating a copy of the Object.

似乎在 PHP 中对象是通过引用传递的。甚至赋值运算符似乎也没有创建对象的副本。

Here's a simple, contrived proof:

这是一个简单的人为证明:

<?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'

?>

In both print cases I am getting 'after'

在这两个印刷案例中,我都在“之后”

So, how do I pass $ato set_b()by value, not by reference?

那么,我如何通过值而不是引用将$a传递给set_b()

回答by Eran Galperin

In PHP 5+ objects are passed by reference. In PHP 4 they are passed by value (that's why it had runtime pass by reference, which became deprecated).

在 PHP 5+ 中,对象是通过引用传递的。在 PHP 4 中,它们是按值传递的(这就是它运行时按引用传递的原因,但它已被弃用)。

You can use the 'clone' operator in PHP5 to copy objects:

您可以使用 PHP5 中的 'clone' 运算符来复制对象:

$objectB = clone $objectA;

Also, it's just objects that are passed by reference, not everything as you've said in your question...

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

回答by yogman

The answers are commonly found in Java books.

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

  1. cloning: If you don't override clone method, the default behavior is shallow copy. If your objects have only primitive member variables, it's totally ok. But in a typeless language with another object as member variables, it's a headache.

  2. serialization/deserialization

  1. 克隆:如果不覆盖克隆方法,默认行为是浅拷贝。如果您的对象只有原始成员变量,那完全没问题。但是在以另一个对象作为成员变量的无类型语言中,这是一个令人头疼的问题。

  2. 序列化/反序列化

$new_object = unserialize(serialize($your_object))

$new_object = unserialize(serialize($your_object))

This achieves deep copy with a heavy cost depending on the complexity of the object.

这取决于对象的复杂性,以高成本实现了深度复制。

回答by Stanislav

According to previous comment, if you have another object as a member variable, do following:

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

class MyClass {
  private $someObject;

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

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

}

Now you can do cloning:

现在您可以进行克隆:

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

回答by Leo

According to the docs (http://ca3.php.net/language.oop5.cloning):

根据文档(http://ca3.php.net/language.oop5.cloning):

$a = clone $b;

回答by Patricio Rossi

Just to clarify PHP uses copy on write, so basically everything is a reference until you modify it, but for objects you need to use clone and the __clone() magic method like in the accepted answer.

只是为了澄清 PHP 在写入时使用复制,所以基本上所有内容都是参考,直到您修改它,但是对于对象,您需要使用 clone 和 __clone() 魔术方法,就像在接受的答案中一样。

回答by Muhammad Ebrahim

In this example we will create iPhoneclass and make exact copy from it by cloning

在这个例子中,我们将创建iPhone类并通过克隆从它复制

class iPhone {

public $name;
public $email;

    public function __construct($n, $e) {

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

    }
}


$main = new iPhone('Dark', '[email protected]');
$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>";

回答by zloctb

This code help clone methods

此代码有助于克隆方法

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());

回答by Pyetro

I was doing some testing and got this:

我正在做一些测试并得到这个:

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

?>

回答by diy_nunez

If you want to fully copy properties of an object in a different instance, you may want to use this technique:

如果要在不同实例中完全复制对象的属性,则可能需要使用此技术:

Serialize it to JSON and then de-serialize it back to Object.

将其序列化为 JSON,然后将其反序列化为 Object。