PHP通过引用传递 - php

让我们假设以下内容:

private $array = array(/*really big multi-dimensional array*/);

public function &func1($specific_large_sub_array_key)
{
     return $this->array[$specific_large_sub_array_key]
}

public function func2()
{
    $specificArray = &$this->func1(1);

    $this->func3($specificArray);
}


public function func3($specificArray)
{
    /* do stuff here*/
}

我的问题是这样的:

如果func3未指定未通过引用传递$ specificArray,那么PHP在func2内部调用func3时是否会复制$ specificArray?还是PHP保留引用并自动传播它?

即这会...

public function func3($specificArray)
{
    unset($specificArray[234]);
}

...影响$ array?

谢谢

注意,此示例已大大简化。

参考方案

PHP如何处理变量和副本非常聪明。

请看以下示例:

// Allocate one variable with content 'Hello'
$var     = 'Hello';

此时,Zend Engine会用内容Hello来表示您的字符串变量。

现在,如果您这样做:

$varCopy = $var;

您有2个独立变量($var$varCopy),但是由于它们的内容相同,因此内容仅存在于内存中的一个位置(基本上尚未创建真实副本)。此时,两个变量在符号表中引用相同的值(Hello)。一旦修改了两个变量之一,它将仅复制内容。同样的逻辑适用于2个副本到任意数量的副本。

简而言之,PHP足够聪明,不必在不需要进行复制的情况下复制变量或数组的值。

您可以在PHP手册的Reference Counting Basics页上了解有关此内容的更多信息。他们甚至在最后给出了一个特定于数组的示例。

memory_get_usage是一个有用的函数,它可以向您显示PHP正在使用多少内存。您可以使用它来跟踪以下事实:当您传递数组的多个副本时,内存使用量几乎不会改变。这可以帮助证明手册参考计数基础部分中概述的要点。

您无需了解有关其工作原理的所有详细信息,但请注意,PHP在创建和管理引用方面很聪明。

编辑:

要直接回答您的实际问题,不,在func3中,PHP不会复制该数组,即使您没有通过引用传递它也是如此。它将使用参考计数基础部分中说明的参考,因此您可以按值传递它,而无需担心。

但是,如果调用unset,则将仅从数组的本地副本中删除您未设置的值,因此除非您通过引用将其传递给函数,否则最终不会将其从源数组中删除。但是按值传递它并不会创建整个巨大阵列的全新副本。即使从副本中删除一个值也不会创建一个完整的副本减去删除的条目(您只有第二个数组,该数组对第一个数组的引用相同,但缺少对删除的条目的一个引用)。

PHP-全局变量的性能和内存问题 - php

假设情况:我在php中运行一个复杂的站点,并且我使用了很多全局变量。我可以将变量存储在现有的全局范围内,例如$_REQUEST['userInfo'],$_REQUEST['foo']和$_REQUEST['bar']等,然后将许多不同的内容放入请求范围内(这将是适当的用法,因为这些数据指的是要求自…

PHP getallheaders替代 - php

我正在尝试从服务器上的apache切换到nginx。唯一的问题是我在PHP脚本中使用的getallheaders()函数,该函数不适用于Nginx。我已经尝试过用户在getallheaders函数上的php站点上提供的注释,但这并不返回所有请求标头。请告诉我如何解决这个问题。我真的想切换到Nginx。 参考方案 您仍然可以使用它,但是您必须像这里一样重新定义…

php-casperjs获取内部文本 - php

我正在为casperjs使用php包装器-https://github.com/alwex/php-casperjs我正在网上自动化一些重复的工作,我需要访问一个项目的innerText,但是我尚不清楚如何从casperjs浏览器访问dom。我认为在js中我会var arr = document.querySelector('label.input…

PHP:将字符串拆分为字母和数字部分的最佳方法 - php

我有几个格式的字符串AA11 AAAAAA1111111 AA1111111 分离字符串的字母和数字部分的最佳方法(最有效)? 参考方案 如果它们都是一系列字母,然后是一系列数字,并且没有非字母数字字符,那么sscanf()可能比regexp更有效$example = 'AAA11111'; list($alpha,$numeric) =…

PHP:检查目录是否为空的最佳和最简便的方法是什么 - php

Improve this question 我有一个包含数百个动态生成文件夹的根目录。随着时间的流逝,在这些目录必须为空的情况下,需要从系统中删除其中一些文件夹。实现这一目标的最佳的最短,最简单和/或最有效的方法是什么? 参考方案 使用glob:if (count(glob("path/*")) === 0 ) { // empty gl…