为啥在 PHP 中通过引用传递?
Posted
技术标签:
【中文标题】为啥在 PHP 中通过引用传递?【英文标题】:Why Passing by Reference in PHP?为什么在 PHP 中通过引用传递? 【发布时间】:2016-03-31 04:18:07 【问题描述】:我写了一个函数,它应该接受一些变量,然后改变这些变量的值。但是,运行该函数后,变量保持不变。然后我做了一些谷歌搜索,发现你需要在变量名前面放一个&
。然后代码做了我想做的事。但是,我不明白您为什么需要输入&
。还有其他方法可以完成我需要做的事情吗?基本上我对通过引用传递的概念感到困惑。这就是我的麻烦开始的地方,大声笑:
到目前为止,在我学过的所有语言(python、java、ruby)中,函数将采用的参数将按照算法中的指示更改变量的值,而无需任何passing by reference
,我认为'刚刚在 php 中发现。为什么 PHP 选择这样做?你能解释一下引用背后的逻辑吗?最后,网上有人说:不要使用引用?如果没有,我还能如何找到我的解决方案。然后在 PHP 中的引用也被弃用了……对不起,这是一个混乱。
我浏览了 PHP 手册以获取参考,但我发现它很难消化。
这是我添加了&
符号的一些代码:
<?php
$comments = "";
$airline_name = "United";
$flight_number = "262";
$departure_airport = "";
function airport(&$one, &$two, &$three, &$four)
if ( !empty($one) || !empty($two) || !empty($three) )
$one = !empty($one) ? "Airline Name: $one<br>" :"Airline Name: PLEASE PROVIDE AIRLINE NAME<br>";
$two = !empty($two) ? "Flight Number: $two<br>" : "Flight Number: PLEASE PROVIDE FLIGHT NUMBER<br>";
$three = !empty($three) ? "Departure Airport: $three<br>" : "Departure Airport: PLEASE PROVIDE DEPARTURE AIRPORT<br>";
$four = !empty($four) ? "Comments: $four<br>" : "";
airport($airline_name,$flight_number,$departure_airport,$comments);
echo $airline_name,$flight_number,$departure_airport,$comments;
?>
【问题讨论】:
那是一种糟糕的编程习惯。传入值,获取新值。这样更易于维护和安全。 ***.com/questions/2157799/… --- ***.com/questions/11360810/… 问题是,为什么? 如果函数将新值作为数组返回,你可以这样做list($var1,$var2) = myFunc()
“在我目前所学的所有语言中,我从来不需要显式地为函数传递参数来修改变量。”那些是什么?
默认情况下,C++ 中的参数是按值传递的 - void foo(int y)
;通过引用传递你使用void foo(int &y)
,或者通过指针传递你使用void foo(int *y)
....还有另一种语言以同样的方式做这件事
【参考方案1】:
一些其他语言不需要这样做的原因是因为它们使用对象:改变对象的状态会反映到指向该对象的所有引用。但是,如果您在 Java 中传递原始类型(如 int
)并更改参数,则不会更改值。 String
s 也是如此,因为您无法修改它们的状态,您只能修改作为参数传递的引用。请注意,它仍然是按值传递,因为您复制的引用基本上是您的方法为对象保存的内容。
PHP 按值传递一个字符串,这意味着 - 至少在概念上 - 在调用它之前制作一个字符串的副本。
尽管如此,通过引用有时被认为是危险的。这是一个在 C 和 C++(甚至 C#)中使用的概念,但像 Java 这样的编程语言不允许这样做。你最好使用输出来修改变量,因为它在语法上是明确的:
function airport($one,$two,$three,$four)
if (!empty($one) || !empty($two) || !empty($three) )
$one = !empty($one) ? "Airline Name: $one<br>" :"Airline Name: PLEASE PROVIDE AIRLINE NAME<br>";
$two = !empty($two) ? "Flight Number: $two<br>" : "Flight Number: PLEASE PROVIDE FLIGHT NUMBER<br>";
$three = !empty($three) ? "Departure Airport: $three<br>" : "Departure Airport: PLEASE PROVIDE DEPARTURE AIRPORT<br>";
$four = !empty($four) ? "Comments: $four<br>" : "";
return array($one,$two,$three,$four);
并调用它:
list($airline_name,$flight_number,$departure_airport,$comments) = airport($airline_name,$flight_number,$departure_airport,$comments);
list
是一个特殊函数,您可以在其中通过引用调用变量(是的,确实如此,它实际上是一种语言结构,如手册中所述)。关键是当您将数组分配给list
构造时,array
中的元素按元素分配给列表中指定的变量。例如(取自here):
list($drink, $color, $power) = array('coffee', 'brown', 'caffeine');
相当于:
$drink = 'coffee';
$color = 'brown';
$power = 'caffeine';
因此它或多或少与array
相反:您将数组拆分为元素并执行元素分配。
使用list
,每个人都清楚这些变量会发生变化。此外,您不必查看函数签名即可知道变量是否会更改:它不会。如果您改变主意并想设置其他变量,那也很容易。
【讨论】:
谢谢!您能否进一步解释答案中的代码?所以你最终返回一个数组,然后你在设置列表时到底在做什么?我以前从未见过。 “一些其他语言不需要这样做的原因是因为它们使用对象:改变对象的状态会反映到指向该对象的所有引用。” PHP 5+ 中的对象也是如此。 “但是,如果您在 Java 中传递原始类型(如 int)并更改参数,则不会更改值。”实际上,无论传递什么类型都是如此。过去的东西不会改变。请注意,不能传递对象,因为“对象”不是值——没有“对象类型”。 Java 中唯一的类型是原始类型和引用类型。在 PHP 5+ 中也是如此——“对象”不是值,您只能处理对象引用。 @newacct:这或多或少是我想要澄清的。因为您只能更改对对象的引用或 tha 值。但这种变化不会反映在调用者身上。以上是关于为啥在 PHP 中通过引用传递?的主要内容,如果未能解决你的问题,请参考以下文章