php数组时按值传递还是按地址传递

本文详细探讨了PHP中数组的赋值方式,并解释了数组赋值实际上是按值传递的原理。文章通过具体示例展示了数组赋值过程中的行为特征,并讨论了PHP内部采用的写时复制机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

php数组时按值传递还是按地址传递

一、总结

1、数组都是按值:php普通变量和数组的赋值(=)是按值传递,对象的赋值(=)是按址传递

2、对象和按值和按址对象的clone(用clone关键字)是按值传递 

 

二、PHP 数组的拷贝是按值传递 or 按引用传递

在记忆中 PHP 简单变量的拷贝是按值传递,数组和对象的拷贝是按引用传递,即通过引用来实现。

简单变量和对象好理解:

<?php

// 简单变量的拷贝
$a = 'human';
$b = $a;
$b = 'cat';
var_dump($a); // string 'human' (length=5)

// 对象的拷贝
class A{}
$a = new A();
$b = $a;
$b->name = 'jack';
var_dump($a); // object(A)[1] public 'name' => string 'jack' (length=4)

对象 $a 和 对象 $b 的内存地址指向了同一个地方,即针对 $a 和 $b 所做的操作都针对同一个实例。

PHP 中可以通过 clone 关键字按值拷贝对象:clone关键字让对象按值传递,因为clone就是拷贝

1
2
3
4
5
6
7
8
9
10
<?php
 
class  A{
     public  $name  'Vardy' ;
}<br>
$a  new  A();
$b  clone  $a ;
$b ->name =  'dee' ;
var_dump( $a );  // object(A)[1] public 'name' => string 'Vardy' (length=5)
var_dump( $b );  // object(A)[2] public 'name' => string 'dee' (length=3)

  

数组:

1
2
3
4
5
6
7
8
9
10
<?php
 
// 数组的拷贝
$a  = [ 'human' 'orc' ];
$b  $a ;
$b [0] =  'elve' ;
var_dump( $a );
// array (size=2)
//   0 => string 'human' (length=5)
//   1 => string 'orc' (length=3)

这样看,数组的拷贝是按值传递的.

 

另一个例子 数组的迭代器:

1
2
3
4
5
6
7
8
9
<?php
 
$a  = [ 'human' 'orc' 'elven' 'undead' ];
next( $a );
 
$b  $a // 此时指针位置也随着数组的复制而复制
 
var_dump(current( $a ));  // string 'orc' (length=3)
var_dump(current( $b ));  // string 'orc' (length=3)

当数组拷贝时,数组的指针位置也随着复制。

(next:http://php.net/manual/zh/function.next.php

current:http://php.net/manual/zh/function.current.php

 

1
2
3
4
5
6
7
8
9
10
<?php
 
$a  = [ 'human' 'orc' 'elven' 'undead' ];
end ( $a );
next( $a );  // 数组指针非法,返回 FALSE
 
$b  $a ;
 
var_dump(current( $a ));  // string 'human' (length=5)
var_dump(current( $b ));  // boolean false

当数组在拷贝前,指针的位置是非法时,拷贝后分别打印两个数组指针所指向的当前单元时,出现了不一样的情况。

原因是数组变量发生拷贝后,两个变量中先发生写操作的,其指针被初始化,即指向第一个元素,而 current 方法也会产生写操作,因此 $a 的数组指针当前指向的是 'human',而 $b  current 方法则返回 FALSE。

 

以下代码同理, $b 首先发生了写操作:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
 
$a  = [ 'human' 'orc' 'elven' 'undead' ];
end ( $a );
next( $a );
 
$b  $a ;
 
$b [] =  'dwarf' ;
 
var_dump(current( $a ));  // boolean false
var_dump(current( $b ));  // string 'human' (length=5)

  

解析:数组的拷贝是值传递。PHP 在管理内存方面有一个机制叫写时复制(COW,Copy On Write),保证了变量间复制值不浪费内存:当一个变量的值复制到另一个变量时,PHP 没有为复制值使用更多的内存,相反,它会更新符号表来说明两个变量拥有相同的内存块,所以当执行下面的代码时并没有创建一个新的数组:

1
2
3
4
<?php
 
$a  = [ 'human' 'orc' 'elven' 'undead' ];
$b  $a ;

当修改了 $a 或 $b 任意一个副本时,PHP 将分配所需的内存来进行复制:

1
$b [] =  'dwarf' ;

  

 

 

参考:

php基础语法之数组和数组指针

php中引用&的真正理解-变量引用、函数引用、对象引用

Programming PHP 3rd Edition

 

参考:

PHP 数组的拷贝是按值传递 or 按引用传递 - 黄棣-dee - 博客园
https://www.cnblogs.com/dee0912/p/5605323.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值