【问题标题】:Confusing Result with array_shift混淆 Result 与 array_shift
【发布时间】:2017-07-11 21:33:31
【问题描述】:

我在 PHP 中使用 array_shift 函数遇到了一些奇怪的行为:

function shift($arr)
{
  array_shift($arr);
}

$a = [1, 2, 3];
shift($a);
print_r($a);

输出:

Array ( [0] => 1 [1] => 2 [2] => 3 ) 

我的预期输出:

Array ( [0] => 2 [1] => 3 ) 

说明:

我相信$a$arr 尽管是不同的引用,但指向同一个数组对象。我希望array_shift 查看$arr 指向的位置并修改(缩短)该数组。然后通过$a 查找数组时可以看到该更改。

但是,当我测试我的理论时,看不到任何变化。该数组与调用 array_shift 之前一样长。什么给了?

【问题讨论】:

  • 为什么不使用 unset 和 array_slice?
  • 不要惊慌的回答解释了你的问题。我确实想指出,自 PHP 5 以来,所有对象都是通过引用传递的,所以这确实会导致混淆,因为在定义参数时,很多时候你不需要使用 '&',并且PHP OOP 的普及,人们经常使用对象,但是对于所有其他变量类型,您需要 '&' 来指定“传递引用”给这个变量。

标签: php parameter-passing


【解决方案1】:

函数中的$arr$a 的数组不同。除非您pass it by reference,否则会创建本地副本,例如

function shift(&$arr) ...

查看the PHP documentation on variable scope:

但是,在用户定义的函数中引入了本地函数范围。默认情况下,函数内使用的任何变量都仅限于本地函数范围。


array_shift 正在按照您期望的方式工作。执行 array_shift 后,您可以在函数内添加 print_r($arr); 以查看函数范围内数组的缩短版本。除非您通过引用传递它,否则它不会影响原始数组。

【讨论】:

  • 哇!这让来自 Java 的我感到惊讶。他们也调用 Java pass-by-value,但它表现出相反的行为。 PHP中的所有对象都是这样吗?例如,如果我将我自己的一个类的实例传递给一个函数,然后调用它的一个方法来更改它,那么该对象在函数之外是否保持不变?
  • 嗯,不,实际上。当您传递一个类的实例时,您实际上是在传递对象标识符而不是实际对象。有点像传递引用,但不是完全相同的东西。但是,数组并不真正被视为对象。我可能应该在我的回答中改变这个措辞。
  • 哦,可以说在 PHP 中传递非数组对象就像在 Java 中传递对象一样工作吗?
  • 老实说,我不确定它在 Java 中是如何工作的,但只要它是函数范围内的同一个对象,实际对象将是,但不是原始类型 (包括数组)将,除非通过引用传递。
  • 感谢您的帮助!
猜你喜欢
  • 2014-07-09
  • 1970-01-01
  • 2016-12-03
  • 2016-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多