以引用方式返回

Ale*_*lex 5 php pass-by-reference

在PHP文档中它说:

不要使用按引用返回来提高性能.引擎将自动对其进行自动优化.

我希望返回一个数组的引用(这是我的类的属性).PHP如何优化它,因为数组不是对象?

如果数组有10亿个条目,如果我没有通过引用传递它,我不会得到两个存储在内存中的10亿条目的数组吗?

Mih*_*ncu 5

PHP使用写入时的副本.这意味着如果您将巨大的数组作为函数参数传递并且只从它读取(例如foreach),您将不会写入它,因此它不需要复制.

$count = count($huge_array); // read the reference at the bottom
for($i = 0; $i < $count $i++) {
    $value = 2*$huge_array[$i]/15;
    if($value > 3)
        $sub_array []= $value;
}
Run Code Online (Sandbox Code Playgroud)

$ subarray应该更小(它是巨大数组的一个子集),只包含所需(已更改)的数据.

如果您不打算更改原始$ huge_array的值,它将永远不会被复制,因此不会使用额外的内存.

如果您打算更改数组的原始值,则需要通过引用传递它.

如果您打算制作并返回原始数组的更改版本,那么您需要 PHP为您分配的额外内存.

如果您打算制作并返回原始数组的更改的较小子集,那么您将创建一个新的空数组,您将从该数组中复制一些数据,并且应该注意不要覆盖$ huge_array中的值,所以你将避免从$ huge_array写作并强调从中读取.

链接说明PHP已针对传递值的用例进行了优化.

只有当变量不是传递给期望值的函数的引用时,才能在写入时复制,如果是,则传递它会触发副本.

这使得PHP本机函数期望参数通过值传递并且接收引用的变量复制引用的值.

function foo(&$data) {
    for ($i = 0; $i < strlen($data); $i++) {
        do_something($data{$i});
    }
}

$string = "... looooong string with lots of data .....";
foo(string);
Run Code Online (Sandbox Code Playgroud)

在C中执行strlen意味着迭代整个字符串来计算它.在PHP中,字符串具有附加的长度值.因此strlen返回从那里读取的值(快速).

但是如果你给它一个引用的变量,它必须在读取它的长度之前复制它,所以它将迭代该值以将其复制到它的参数列表中,读取并返回长度(然后释放新复制的字符串的内存) .