php数组时按值传递还是按地址传递
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
|
<?phpclass 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 falsevar_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'; |
参考:
Programming PHP 3rd Edition
参考:
PHP 数组的拷贝是按值传递 or 按引用传递 - 黄棣-dee - 博客园
https://www.cnblogs.com/dee0912/p/5605323.html
php数组时按值传递还是按地址传递的更多相关文章
- c语言进阶9-值传递与地址传递
一. 函数的值传递 函数的值传递是指参数为基本类型时,如整型.浮点型.字符型(特指单字符型)时,参数传递时是从实参拷贝一份值传给形参,形参的变化不会影响实参的值. 1. 基本类型做参数 ...
- Java中不得不谈的值传递和地址传递
个人的一些认识,希望能对初学Java的你,或者困惑于方法参数传递的你祈祷一丝帮助! 下面是一些作者的个人观点,如果有错,欢迎各位大牛指出错误,灰常感谢您的观看与支持... -------------- ...
- JavaScript中,按值传递与按地址(引用)传递。
JavaScript中,数字型,字符串,布尔型等基本类型,传递给变量时,传递方式为按值传递,这个很好理解,不做多解释. 而令人有所疑惑的,是数组,对象等引用类型传递给变量是,传递方式为按地址传递.此处 ...
- JavaScript中函数参数的按值传递与按引用传递(即按地址传递)
首先声明一句:JavaScript中所有函数的参数都是按值传递的!不存在按引用传递! 在讲传递参数之前我们先来讲一下指针. 学过C指针的应该都知道,指针变量中保存的是一个地址,程序可以根据所保存的地址 ...
- java学习——java按值传递和按址传递
先复制一个面试/笔试的题: 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答案: 是值传递.Java语言的方法调用只支持参 ...
- 按值传递 vs. 按指针传递
按值传递还是指针传递? 变量赋值有两种方式:按值传递.按"指针"传递(指针也常称为"引用").不同的编程语言赋值的方式不一样,例如Python是按"指 ...
- C语言中数组名作为参数进行函数传递
用数组名作函数参数与用数组元素作实参有几点不同. 1) 用数组元素作实参时,只要数组类型和函数的形参变量的类型一致,那么作为下标变量的数组元素的类型也和函数形参变量的类型是一致的.因此,并不要求函数的 ...
- C++中函数的形参为数组时,实质形参是指针
C++中函数的形参如果为数组的话,那么进行实参传递时,实参实际上换转化成指针.参考下面的例子: #include<iostream> using namespace std; void f ...
- C语言 值传递和地址传递
不少同学在学到C语言的指针部分时感到很困惑,对经常提到的"值传递"和"地址传递"两个概念弄不 明白.实际上,因为地址本身也可以作为一个特殊的"值&qu ...
随机推荐
- 05-数据类型转换(bool类型)
- 【Codeforces Round #422 (Div. 2) C】Hacker, pack your bags!(二分写法)
[题目链接]:http://codeforces.com/contest/822/problem/C [题意] 有n个旅行计划, 每个旅行计划以开始日期li,结束日期ri,以及花费金钱costi描述; ...
- java 自己定义异常,记录日志简单说明!留着以后真接复制
log4j 相关配制说明:http://blog.csdn.net/liangrui1988/article/details/17435139 自己定义异常 package org.rui.Excep ...
- EventBus框架原理解析(结合源代码)(上)
上一篇文章http://blog.csdn.net/crazy__chen/article/details/47425779 和大家一起模仿EventBus的实现机制.和大家一起写出了一个简易的Eve ...
- 九度OJ 1070 今年的第几天?(模拟)
题目1070:今年的第几天? 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3491 解决:1936 题目描写叙述: 输入年.月.日,计算该天是本年的第几天. 输入: 包含三个整数年(1& ...
- OC07 -- 迭代器/NSNumber/NSValue/NSRange/NSSet/NSDate 及相互转换.(杂)
//一: 迭代器 //数组 NSArray *arr=@[@"1",@"2",@"3",@"4",@"5&qu ...
- [UOJ#334][NOIP2017]列队 平衡树/线段树/树状数组
题目链接 题意不说了,一辈子也忘不掉 解法1.平衡树 这题就是平衡树裸题,每一行开一棵维护前 \(m-1\) 个,最后一列单独维护,因为很多人没有用到,所以平衡树每个节点是一个区间(pair),分裂时 ...
- USACO2002 Open:雄伟的山峦
简要题意: 奶牛们在落基山下避暑,从它们的房子向外望去,可以看到N 座山峰构成的山峦,奶牛发现每座山峰都是等腰三角形,底边长度恰好是高度的两倍.所以山峰的顶点坐标可由两个底部端点求出.设i 座第山峰的 ...
- 机器学习(四) 分类算法--K近邻算法 KNN (上)
一.K近邻算法基础 KNN------- K近邻算法--------K-Nearest Neighbors 思想极度简单 应用数学知识少 (近乎为零) 效果好(缺点?) 可以解释机器学习算法使用过程中 ...
- jquery<=======>js实现方法
http://haorooms.com/post/js_shixian_jquery