PHP|关于对象复制的一些事

niecprea

先看对象复制的代码

class CopyMe{}
$first = new CopyMe();
$second = $first;

在PHP5及以后的版本,$first & $second指向同一个对象。

在PHP中,对象的赋值和传递都是通过引用进行的。

当我们需要一个对象的副本时,可以这么做:

class CopyMe{}
$first = new CopyMe();
$second = clone $first;

通过clone关键字,使用值复制方式新生成一个对象。

但是这有一个问题,对象中的某些数据,比如id,我不想是一样的。但是clone是做不到的。

这时我们可以通过实现一个特殊的方法__clone()来达到这个目的。当一个对象调用clone关键字时,其__clone()方法就会被自动调用。

class Person
{
    public private $id;
    
    public function __construct() {}
    
    public function setId($id) {
        $this->id = $id;
    }

    public function __clone() {
        $this->id = 0;
    }
}

$person = new Person();
$person->setId(343);
$person2 = clone $person;

这样的赋值属于浅复制(shallow copy),可以保证所有基本数据类型的属性被完全复制。

如果我们不希望对象的属性的属性被共享,例如:

class Account
{
    public $balance;
    public function __construct($balance) {
        $this->balance = $balance;
    }
}

class Person
{
    private $name;
    private $age;
    private $id;
    public $account;
    
    public function __construct($name, $age, Account $account) {
        $this->name = $name;
        $this->age = $age;
        $this->account = $account;
    }
    
    public function setId($id) {
        $this->id = $id;
    }
    
    public function __clone() {
        $this->id = 0;
    }
}

$person = new Person('bob', 43, new Account(200));
$person->setId(433);
$person2 = clone $person;

$person->account->balance += 10;
print $person2->account->balance;

得到的结果: 210

实际上我并不想让$person2的账户价格受到另一个对象的影响。

可以显式的在__clone方法中复制指向的对象。

function __clone() {
    $this->id = 0;
    $this->account = clone $this->account;
}
阅读 1.5k

ThinkingPool
Y1RReE5qazFOVFl5

Hello world!

856 声望
21 粉丝
0 条评论
你知道吗?

Hello world!

856 声望
21 粉丝
宣传栏