php对象深浅拷贝问题

1 简介

  • php中,普通类型(包括array)为值拷贝;对象是引用(实质是拷贝了对象标识符,通过它可以访问到真正的对象,即new class时便是引用了)

  • php5之后,=、做参数(无论是否带前置&)都是对class的引用(浅拷贝)

  • 推荐用序列化深拷贝:unserialize(serialize($one))、json_decode(json_encode($one))

2 示例

1. 综合测试

<?php
// 下面列举三种情况:

// 1.对象做参数,或者被use
class Person{
    public $name = "";
    public function __construct($name){
        $this->name = $name;
    }
}
$aman = new Person('man');
function change( $p){
    $p->name = 'lucy';
}
// 浅拷贝
change($aman);
echo $aman->name, "\n"; //lucy

// 2.数组
$stu = array(
    'name' => 'lilei',
    'sex' => 'male'
);
// 普通类型深拷贝
function foo($arr){
    $arr['name'] = 'hanmeimei';
    return $arr;
}
foo($stu);
var_dump($stu); 

// 3.对象数组
$people = array(
    'a' => new Person("aaaaa"),
    'b' => new Person("bbbbb"),
);
// 值为对象,浅拷贝
function changeOne($arr){
    $arr['a']->name = 'lucy2';
}
changeOne($people);
var_dump($people);

2. 对类进行集中测试

<?php
class Test {
    public $f = "first";
}

class TestOne {
    public $a = 1;
    public $ac = null;

    public function __construct()
    {
        $this->ac = new Test();
    }

    // __clone时需要修改的代码
    public function __clone()
    {
        $this->ac = clone $this->ac;
    }
}

$one = new TestOne();
echo "原值: ", $one->a, " ", $one->ac->f, "\n";

// =赋值:完全浅拷贝:$one的普通属性、class属性
//$two = $one;
//$two->a = 2;
//$two->ac->f = "second";
//echo "=赋值:", $one->a, " ", $one->ac->f, "\n";

// clone:部分浅拷贝:深拷贝$one的普通属性、浅拷贝class属性
//$three = clone $one;
//$three->a = 2;
//$three->ac->f = "second";
//echo "clone:", $one->a, " ", $one->ac->f, "\n";

// __clone添加逻辑:完全深拷贝,依赖编码(有嵌套的问题:类属性里面还有类属性,不推荐这样):$one的普通属性、class属性
//$four = clone $one;
//$four->a = 2;
//$four->ac->f = "second";
//echo "__clone:", $one->a, " ", $one->ac->f, "\n";

// serialize\json序列化赋值:完全深拷贝,$one的普通属性、class属性
//$five = unserialize(serialize($one));
//$five->a = 2;
//$five->ac->f = "second";
//echo "serialize:", $one->a, " ", $one->ac->f, "\n";
$five = json_decode(json_encode($one));
$five->a = 2;
$five->ac->f = "second";
echo "serialize:", $one->a, " ", $one->ac->f, "\n";

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值