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

这篇博客详细探讨了PHP中数组参数传递的三种情况:只读取、修改和明确引用。作者指出,即使没有使用`&`符号,PHP在不修改数组的情况下也会以引用方式内部处理,避免了不必要的内存复制。当修改数组时,PHP会创建数组的副本。文章通过内存使用量的测量来验证这些行为,并强调理解这些细节对于优化代码和管理内存至关重要。
摘要由CSDN通过智能技术生成

TL; DR

a)方法/函数只读取数组参数=> 隐式(内部)引用

b)方法/函数修改数组参数=> 值

c)方法/函数数组参数被明确标记为引用(带有&符号)=> 显式(用户土地)参考

或这个:

- 非&符号数组参数:通过引用传递; 写操作改变了数组的新副本,在第一次写入时创建的副本;

- &符号数组参数:通过引用传递; 写入操作改变了原始数组。

记住 - 当你写入非&符号数组参数时,PHP会进行值复制。 这就是$arr的意思。 我很想向你展示这种行为的C源,但它在那里很可怕。 更好地使用xdebug_debug_zval()。

帕斯卡马丁是对的。 Kosta Kontos更是如此。

回答

这取决于。

长版

我想我正在为自己写这篇文章。 我应该有博客或其他东西......

每当人们谈论引用(或指针,就此而言)时,它们通常会陷入一种逻辑上(只看这个线程!)。

PHP是一种古老的语言,我认为我应该加入混乱(尽管这是对上述答案的总结)。 因为,虽然两个人可以在同一时间做对,但你最好只是将他们的头脑合而为一。

首先,如果你不以黑白方式回答,你应该知道你不是一个学究。 事情比“是/否”更复杂。

正如您将看到的那样,整个按值/按引用的内容与您在方法/函数范围内对该数组的确切做法非常相关:读取它还是修改它?

PHP说什么? (又名“改变”)

手册说明了这一点(强调我的):

默认情况下,函数参数按值传递(如果是,则传递   函数内的参数值改变了,它没有得到   在功能之外改变了)。 允许函数修改它   参数,必须通过引用传递。

要争论一个   函数总是通过引用传递,在&符号前加上&符号   函数定义中的参数名称

据我所知,当大,严肃,诚实的上帝程序员谈论引用时,他们通常会谈论改变该引用的价值。 而这正是手册所述的内容:$arr。

还有一个案例,他们没有提到,如果我不改变任何东西怎么办 - 只读?

如果将数组传递给未明确标记引用的方法,并且我们不在函数范围中更改该数组,该怎么办?又名:

function printArray($array) {}

$x = array(1);

printArray($x);

继续阅读,我的同路人。

PHP实际上做了什么? (又名“记忆”)

相同的大而严肃的程序员,当他们变得更加严肃时,他们会谈论有关引用的“内存优化”。 PHP也是如此。 因为$arr,这就是原因。

将HUGE数组传递给各种函数并不是理想的,并且PHP要复制它们(毕竟这就是“传值”所做的):

// filling an array with 10000 elements of int 1

// let's say it grabs 3 mb from you RAM

$x = array_fill(0, 10000, 1);

// pass by value, right? RIGHT?

function readArray($arr) { //

echo count($arr); // let's just read the array

}

readArray($x);

那么现在,如果这实际上是按值传递,我们会有3mb + RAM消失,因为该阵列有两个副本,对吧?

错误。 只要我们不更改$arr变量,那就是内存方式的引用。 你只是没有看到它。 这就是为什么PHP在谈到1331840时提到用户土地参考,以区分内部和显式(带&符号)。

事实

所以,$arr

我想出了三个(是的,三个)案例:

a)方法/函数只读取数组参数

b)方法/函数修改数组参数

c)方法/函数数组参数被明确标记为引用(带符号)

首先,让我们看看阵列实际吃多少内存(在这里运行):

$start_memory = memory_get_usage();

$x = array_fill(0, 10000, 1);

echo memory_get_usage() - $start_memory; // 1331840

那很多字节。 大。

a)方法/函数只读取数组参数

现在让我们创建一个只读取所述数组作为参数的函数,我们将看到读取逻辑占用多少内存:

function printUsedMemory($arr)

{

$start_memory = memory_get_usage();

count($arr); // read

$x = $arr[0]; // read (+ minor assignment)

$arr[0] - $arr[1]; // read

echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading

}

$x = array_fill(0, 10000, 1); // this is 1331840 bytes

printUsedMemory($x);

想猜? 我80岁了! 你自己看。 这是PHP手册省略的部分。 如果$arr参数实际上是按值传递的,那么您会看到类似于1331840字节的内容。 似乎$arr的行为就像一个参考,不是吗? 那是因为它是一个参考 - 一个内部参考。

b)方法/函数修改数组参数

现在,让我们写一下这个参数,而不是从中读取:

function printUsedMemory($arr)

{

$start_memory = memory_get_usage();

$arr[0] = 1; // WRITE!

echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading

}

$x = array_fill(0, 10000, 1);

printUsedMemory($x);

再次,看看你自己,但是,对我来说,这非常接近1331840.所以在这种情况下,数组实际上被复制到$arr。

c)方法/函数数组参数被明确标记为引用(带符号)

现在让我们看看显式引用的写操作需要多少内存(在这里运行) - 注意函数签名中的&符号:

function printUsedMemory(&$arr) //

{

$start_memory = memory_get_usage();

$arr[0] = 1; // WRITE!

echo memory_get_usage() - $start_memory; // let's see the memory used whilst reading

}

$x = array_fill(0, 10000, 1);

printUsedMemory($x);

我打赌你最多可以获得200分! 因此,这与从非&符号参数读取的内存大致相同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值