PHP中的数组是通过值还是通过引用传递的?

PHP中的数组是通过值还是通过引用传递的?

当一个数组作为参数传递给方法或函数时,它是通过引用传递的吗?

这样做怎么样:

$a = array(1,2,3);$b = $a;

$b参考$a


慕婉清6462132
浏览 1007回答 3
3回答

largeQ

对于问题的第二部分,请参阅手册的数组页面,其中说明(引用):数组赋值始终涉及值复制。使用引用运算符通过引用复制数组。给出的例子:<?php$arr1 = array(2, 3);$arr2 = $arr1;$arr2[] = 4; // $arr2 is changed,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// $arr1 is still array(2, 3)$arr3 = &$arr1;$arr3[] = 4; // now $arr1 and $arr3 are the same?>对于第一部分,最好的方法是尝试;-)考虑这个代码示例:function my_func($a) {&nbsp; &nbsp; $a[] = 30;}$arr = array(10, 20);my_func($arr);var_dump($arr);它会给出这个输出:array&nbsp; 0 => int 10&nbsp; 1 => int 20这表明函数没有修改作为参数传递的“外部”数组:它作为副本传递,而不是引用。如果你想通过引用传递它,你将不得不修改函数,这样:function my_func(& $a) {&nbsp; &nbsp; $a[] = 30;}输出将变为:array&nbsp; 0 => int 10&nbsp; 1 => int 20&nbsp; 2 => int 30因为,这次,数组已经“通过引用”传递。不要犹豫,阅读手册中的参考文献解释部分:它应该回答你的一些问题;-)

茅侃侃

关于你的第一个问题,数组是通过引用传递的,除非它在你调用的方法/函数中被修改。如果您尝试在方法/函数中修改数组,则首先创建它的副本,然后仅修改副本。这使得它看起来好像数组是按值传递的,而事实上并非如此。例如,在第一种情况下,即使您没有通过引用定义函数接受$ my_array(通过使用参数定义中的&字符),它仍然通过引用传递(即:您不浪费内存用不必要的副本)。function&nbsp;handle_array($my_array)&nbsp;{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;...&nbsp;read&nbsp;from&nbsp;but&nbsp;do&nbsp;not&nbsp;modify&nbsp;$my_array &nbsp;&nbsp;&nbsp;&nbsp;print_r($my_array); &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;...&nbsp;$my_array&nbsp;effectively&nbsp;passed&nbsp;by&nbsp;reference&nbsp;since&nbsp;no&nbsp;copy&nbsp;is&nbsp;made}但是,如果修改数组,则首先创建它的副本(使用更多内存但不会影响原始数组)。function&nbsp;handle_array($my_array)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;...&nbsp;modify&nbsp;$my_array &nbsp;&nbsp;&nbsp;&nbsp;$my_array[]&nbsp;=&nbsp;"New&nbsp;value"; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;...&nbsp;$my_array&nbsp;effectively&nbsp;passed&nbsp;by&nbsp;value&nbsp;since&nbsp;requires&nbsp;local&nbsp;copy}仅供参考 - 这被称为“懒惰副本”或“写入时复制”。

繁星淼淼

a)方法/函数只读取数组参数=>&nbsp;隐式(内部)引用b)方法/函数修改数组参数=>&nbsp;值c)方法/函数数组参数显式标记为引用(带符号) =>&nbsp;显式(用户 - 土地)参考或者:-&nbsp;非&符号数组参数:通过引用传递;&nbsp;写操作改变了数组的新副本,在第一次写入时创建的副本;&nbsp;-&nbsp;&符号数组参数:通过引用传递;&nbsp;写入操作改变了原始数组。记住 -&nbsp;当你写入非&符号数组参数时,PHP会进行值复制。这copy-on-write意味着什么。我很想向你展示这种行为的C源,但它在那里很可怕。更好地使用xdebug_debug_zval()。帕斯卡马丁是对的。Kosta Kontos更是如此。回答这取决于。长版我想我正在为自己写这篇文章。我应该有博客或其他东西......每当人们谈论引用(或指针,就此而言)时,他们通常会陷入一种逻辑上(只看这个线程!)。PHP是一种古老的语言,我认为我应该加入混乱(尽管这是对上述答案的总结)。因为,虽然两个人可以在同一时间做对,但你最好只是将他们的头脑合而为一。首先,如果你不以黑白方式回答,你应该知道你不是一个学究。事情比“是/否”更复杂。正如您将看到的那样,整个按值/按引用的内容与您在方法/函数范围内对该数组的确切做法非常相关:读取它还是修改它?PHP说什么?(又名“改变”)该手册说,这(重点煤矿):默认情况下,函数参数按值传递(因此,如果函数中的参数值发生更改,则不会在函数外部进行更改)。要允许函数修改其参数,必须通过引用传递它们。要使函数的参数始终通过引用传递,请在函数定义中为参数名称添加一个与号(&)据我所知,当大,严肃,诚实的上帝程序员谈论引用时,他们通常会谈论改变该引用的价值。而这正是手册所说的:hey, if you want to CHANGE the value in a function, consider that PHP's doing "pass-by-value"。还有一个案例,他们没有提到,如果我不改变任何东西怎么办?如果将数组传递给未明确标记引用的方法,并且我们不在函数范围中更改该数组,该怎么办?例如:<?phpfunction&nbsp;readAndDoStuffWithAnArray($array)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;$array[0]&nbsp;+&nbsp;$array[1]&nbsp;+&nbsp;$array[2];}$x&nbsp;=&nbsp;array(1,&nbsp;2,&nbsp;3);echo&nbsp;readAndDoStuffWithAnArray($x);继续阅读,我的同路人。PHP实际上做了什么?(又名“记忆”)相同的大而严肃的程序员,当他们变得更加严肃时,他们会谈论有关引用的“内存优化”。PHP也是如此。因为PHP is a dynamic, loosely typed language, that uses copy-on-write and reference counting,这就是原因。将HUGE数组传递给各种函数并不是理想的,并且PHP要复制它们(毕竟这就是“传值”所做的):<?php//&nbsp;filling&nbsp;an&nbsp;array&nbsp;with&nbsp;10000&nbsp;elements&nbsp;of&nbsp;int&nbsp;1//&nbsp;let's&nbsp;say&nbsp;it&nbsp;grabs&nbsp;3&nbsp;mb&nbsp;from&nbsp;your&nbsp;RAM$x&nbsp;=&nbsp;array_fill(0,&nbsp;10000,&nbsp;1);&nbsp;//&nbsp;pass&nbsp;by&nbsp;value,&nbsp;right?&nbsp;RIGHT?function&nbsp;readArray($arr)&nbsp;{&nbsp;//&nbsp;<--&nbsp;a&nbsp;new&nbsp;symbol&nbsp;(variable)&nbsp;gets&nbsp;created&nbsp;here &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;count($arr);&nbsp;//&nbsp;let's&nbsp;just&nbsp;read&nbsp;the&nbsp;array}readArray($x);那么现在,如果这实际上是按值传递,我们会有3mb + RAM消失,因为该阵列有两个副本,对吧?错误。只要我们不改变$arr变量,那就是内存方面的参考。你只是没有看到它。这就是为什么PHP&nbsp;在谈论时提到&nbsp;用户土地引用&$someVar,以区分内部和显式(与&符号)。事实所以,&nbsp;when an array is passed as an argument to a method or function is it passed by reference?我想出了三个(是的,三个)情况:a)方法/函数只读取数组参数b)方法/函数修改数组参数c)方法/函数数组参数被明确标记为引用(带有号)首先,让我们看看阵列实际吃多少内存(在这里运行):<?php $start_memory&nbsp;=&nbsp;memory_get_usage();$x&nbsp;=&nbsp;array_fill(0,&nbsp;10000,&nbsp;1);echo&nbsp;memory_get_usage()&nbsp;-&nbsp;$start_memory;&nbsp;//&nbsp;1331840那很多字节。大。a)方法/函数只读取数组参数现在让我们创建一个只读取所述数组作为参数的函数,我们将看到读取逻辑占用多少内存:<?phpfunction&nbsp;printUsedMemory($arr)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;$start_memory&nbsp;=&nbsp;memory_get_usage(); &nbsp;&nbsp;&nbsp;&nbsp;count($arr);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;read &nbsp;&nbsp;&nbsp;&nbsp;$x&nbsp;=&nbsp;$arr[0];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;read&nbsp;(+&nbsp;minor&nbsp;assignment) &nbsp;&nbsp;&nbsp;&nbsp;$arr[0]&nbsp;-&nbsp;$arr[1];&nbsp;//&nbsp;read &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;memory_get_usage()&nbsp;-&nbsp;$start_memory;&nbsp;//&nbsp;let's&nbsp;see&nbsp;the&nbsp;memory&nbsp;used&nbsp;whilst&nbsp;reading}$x&nbsp;=&nbsp;array_fill(0,&nbsp;10000,&nbsp;1);&nbsp;//&nbsp;this&nbsp;is&nbsp;1331840&nbsp;bytesprintUsedMemory($x);想猜?我80岁了!亲眼看看。这是PHP手册省略的部分。如果$arrparam实际上是按值传递的,那么你会看到类似于1331840字节的东西。它似乎$arr表现得像一个参考,不是吗?那是因为它是一个参考 - 一个内部参考。b)方法/函数修改数组参数现在,让我们写一下这个参数,而不是从中读取:<?phpfunction&nbsp;printUsedMemory($arr){ &nbsp;&nbsp;&nbsp;&nbsp;$start_memory&nbsp;=&nbsp;memory_get_usage(); &nbsp;&nbsp;&nbsp;&nbsp;$arr[0]&nbsp;=&nbsp;1;&nbsp;//&nbsp;WRITE! &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;memory_get_usage()&nbsp;-&nbsp;$start_memory;&nbsp;//&nbsp;let's&nbsp;see&nbsp;the&nbsp;memory&nbsp;used&nbsp;whilst&nbsp;reading}$x&nbsp;=&nbsp;array_fill(0,&nbsp;10000,&nbsp;1);printUsedMemory($x);再次,看到自己,但对我来说,那是相当接近所以在这种情况下是1331840.,该阵列是实际上被复制到$arr。c)方法/函数数组参数被明确标记为引用(带符号)现在让我们看看显式引用的写操作需要多少内存(在这里运行) - 注意函数签名中的&符号:<?phpfunction&nbsp;printUsedMemory(&$arr)&nbsp;//&nbsp;<-----&nbsp;explicit,&nbsp;user-land,&nbsp;pass-by-reference{ &nbsp;&nbsp;&nbsp;&nbsp;$start_memory&nbsp;=&nbsp;memory_get_usage(); &nbsp;&nbsp;&nbsp;&nbsp;$arr[0]&nbsp;=&nbsp;1;&nbsp;//&nbsp;WRITE! &nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;memory_get_usage()&nbsp;-&nbsp;$start_memory;&nbsp;//&nbsp;let's&nbsp;see&nbsp;the&nbsp;memory&nbsp;used&nbsp;whilst&nbsp;reading}$x&nbsp;=&nbsp;array_fill(0,&nbsp;10000,&nbsp;1);printUsedMemory($x);我打赌你最多可以获得200分!因此,这与从非&符号参数读取的内存大致相同。
打开App,查看更多内容
随时随地看视频慕课网APP