PHP变量:引用还是副本

PHP变量:引用还是副本,php,return-by-reference,Php,Return By Reference,我对PHP变量引用的工作原理感到困惑。在下面的示例中,我希望能够以$bar[0]或$barstack[0][0]的形式访问字符串hello。似乎在步骤1中通过引用传递数组就足够了 第二个例子不起作用$foostack[0]0]是字符串hello,但$foo[0]不存在。在某种程度上,$foostack的第一个元素将成为$foo的副本,而不是引用 问题在于步骤2的第一行:当我打开一个引用时,我希望弹出一个引用。但是array\u pop会返回一个副本 其他人告诉我,如果我不得不担心引用和副本,那么

我对PHP变量引用的工作原理感到困惑。在下面的示例中,我希望能够以
$bar[0]
$barstack[0][0]
的形式访问字符串hello。似乎在步骤1中通过引用传递数组就足够了

第二个例子不起作用
$foostack[0]0]
是字符串hello,但
$foo[0]
不存在。在某种程度上,$foostack的第一个元素将成为$foo的副本,而不是引用

问题在于步骤2的第一行:当我打开一个引用时,我希望弹出一个引用。但是
array\u pop
会返回一个副本

其他人告诉我,如果我不得不担心引用和副本,那么PHP就不是适合我的语言。这可能是我得到的最好的答案

FWIW,为了使
var_dump
有用,它需要显示一些区分引用和副本的属性。事实并非如此。也许还有其他功能

我的第一个PHP项目似乎进展得很糟糕。有人能帮我解释一下这件事吗 这个代码有问题吗


您的代码运行良好,没有bug,并且独立于PHP4或PHP5。如果能简单地向你解释一下,也许会有帮助

让我们看一看在你眼中不起作用的例子,看看实际发生了什么:

// step 1
$foo = array(); # 1.
$foostack = array( &$foo ); # 2.
  • 1.:将变量
    $foo
    初始化为空数组
  • 2.将变量
    $foostack
    初始化为数组,数组的第一个元素是变量
    $foo
    的别名。这与编写完全相同:
    $foostack[]=&$foo
进入下一步:

// step 2
$last = array_pop($foostack); # 3.
array_push($last, 'hello'); # 4.
array_push($foostack, &$last); # 5.
  • 3.将数组
    $foostack
    的最后一个元素的值指定给
    $last
    ,然后从数组
    $foostack
    中删除最后一个元素注意:
    array\u pop
    返回值,而不是引用
  • 4.:将
    'hello'
    作为新元素添加到
    $last
    中的空数组中
  • 5.:将
    和$last
    作为新元素添加到
    $foostack
那么我们现在有哪些变量呢

  • 首先,
    $foo
    ,它只包含一个空数组。
    $foostack
    的最后一个元素曾经引用过它(2.),但是您已经在(3.)之后直接删除了它。由于
    $foo
    且其值不再更改,因此它只是一个空数组
    array()
  • 然后是
    $last
    ,它在3中得到一个空数组。。这只是一个空数组,它是一个值而不是一个引用。在(4.)中,将字符串
    'hello'
    作为第一个元素添加到其中
    $last
    是一个数组,其中包含一个字符串元素
  • 然后是
    $foostack
    。它是一个数组,在(2.)中获取对
    $foo
    的引用,然后在(3.)中删除该引用。最后,
    $last
    的别名被添加到它
这正是其余代码的输出:

echo count($foostack[0]) .';'. count($foo);
$foostack[0]
$last
的别名-字符串
'hello'
作为唯一元素的数组,而
$foo
只是
$foo
,空数组
数组()

如果用PHP4或PHP5执行,则没有区别


当你写这是“错误的”时,我想你只是无法实现你想要的。您可能正在寻找一个函数,该函数能够在删除数组的最后一个元素之前返回对该元素的引用。让我们调用该函数
array\u pop\u ref()

array\u pop\u ref
功能:

function &array_pop_ref(&$array)
{
    $result = NULL;
    if (!is_array($array)) return $result;
    $keys = array_keys($array);
    $end = end($keys);
    if (false === $end) return $result;
    $result =& $array[$end];
    array_pop($array);
    return $result;
}

邮寄前请亲自检查。您可以使用var_dump($array),这将告诉您数组中有什么。在我看来,这个问题似乎不符合法律的规定StackOverflow@Sunny吉姆-为了得到更好的回答,试着在你的问题中加入你期望发生的事情和实际发生的事情。其中一半在你的链接中,但另一半没有。@Sunny Jim:刚刚看到你更新了你的问题
var_dump
显示引用,在值前面用
&
发出信号。我添加了一个答案,一步一步地解释了发生了什么,我想您只是缺少了
array\u pop
始终返回一个值,而不是一个引用/别名。我在下面也添加了一个工作示例。谢谢。这至少是一个小时的咨询!PHP手册中也有关于这个主题的更多信息(事实上相当多),我认为将引用视为变量别名是个好主意。请参见此处:。
// step 1
$foo = array();
$foostack = array( &$foo );

// step 2
$last =& array_pop_ref($foostack);
array_push($last, 'hello');
array_push($foostack, &$last);

// results
echo count($foostack[0]) .';' .count($foo); # 1;1
function &array_pop_ref(&$array)
{
    $result = NULL;
    if (!is_array($array)) return $result;
    $keys = array_keys($array);
    $end = end($keys);
    if (false === $end) return $result;
    $result =& $array[$end];
    array_pop($array);
    return $result;
}