为什么要在 PHP 中通过引用传递?

Why Passing by Reference in PHP?

提问人:Govind Rai 提问时间:12/25/2015 最后编辑:willeM_ Van OnsemGovind Rai 更新时间:12/30/2015 访问量:140

问:

我编写了一个函数,该函数应该接受一些变量,然后更改这些变量的值。但是,在运行该函数后,变量保持不变。然后我做了一些谷歌搜索,发现你需要在变量名前面放一个。然后代码做了我想做的事情。但是,我不明白为什么您需要将 .有没有其他方法可以完成我需要做的事情?基本上,我对通过引用传递的概念感到困惑。这就是我的困境开始的地方,哈哈:&&

在我目前学到的所有语言(python、java、ruby)中,函数所采用的参数会按照算法中的指示更改变量的值,而没有任何,这是我刚刚在 PHP 中发现的概念。为什么PHP选择这样做?您能解释一下参考文献背后的逻辑吗?最后,网络上到处都是人说:不要使用引用?如果没有,我还能如何找到我的解决方案。然后还有 PHP 中引用的弃用......对不起,这是一团糟。passing by reference

我浏览了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;

?>
PHP 按引用 传递值

评论

3赞 John Conde 12/25/2015
这是一种糟糕的编程实践。传入值,获取新值。这更易于维护,也更安全。
2赞 Funk Forty Niner 12/25/2015
stackoverflow.com/questions/2157799/......---stackoverflow.com/questions/11360810/......问题是,为什么?
0赞 MDEV 12/25/2015
如果函数以数组形式返回新值,您可以执行以下操作list($var1,$var2) = myFunc()
2赞 Axalix 12/25/2015
“在我迄今为止学习的所有语言中,我从来没有显式地传递函数的参数来修改变量。那些是哪些?
0赞 Mark Baker 12/25/2015
默认情况下,C++ 中的参数按值 - 传递;要通过引用来传递,请使用 ,或者要通过指针来传递,请使用 ....还有另一种语言以同样的方式做到这一点void foo(int y)void foo(int &y)void foo(int *y)

答:

4赞 willeM_ Van Onsem 12/25/2015 #1

其他一些语言不需要这样做的原因是因为它们使用对象:更改对象的状态会反映到指向该对象的所有引用中。但是,如果您在 Java 中传递一个基元类型(如 )并更改了参数,则该值不会被更改。同样的故事也适用于 s,因为您无法修改它们的状态,因此只能修改作为参数传递的引用。请注意,它仍然是按值传递的,因为您复制了引用,这基本上是您的方法对对象的引用。intString

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 是一个特殊的函数,您可以在其中通过引用调用变量(是的,您确实这样做,它实际上是一种语言结构,如手册中所述)。关键是,当您将数组分配给构造时,将 中的元素逐个分配给列表中指定的变量。例如(取自此处):listarray

list($drink, $color, $power) = array('coffee', 'brown', 'caffeine');

相当于:

$drink = 'coffee';
$color = 'brown';
$power = 'caffeine';

因此,它或多或少与:您将数组拆分为元素并执行元素分配相反。array


使用 ,每个人都清楚这些变量会发生变化。此外,您不必查看函数签名即可知道变量是否会更改:它不会。如果您改变主意并想设置其他变量,那也很容易。list

评论

0赞 Govind Rai 12/25/2015
谢谢!你能进一步解释一下你的回答中的代码吗?所以你最终返回一个数组,然后当你设置列表时你到底在做什么?我以前从未见过。
1赞 newacct 12/25/2015
“其他一些语言不需要这样做的原因是因为它们使用对象:改变对象的状态会反映到指向该对象的所有引用中。PHP 5+ 中的对象也是如此。
1赞 newacct 12/25/2015
“但是,如果你在 Java 中传递一个原始类型(如 int)并更改参数,则该值不会被更改。实际上,无论传递什么类型,这都是正确的。通过的东西不会被改变。请注意,对象不能传递,因为“对象”不是值,没有“对象类型”。Java 中唯一的类型是基元类型和引用类型。在 PHP 5+ 中也是如此——“对象”不是值,你只能处理对象引用。
0赞 willeM_ Van Onsem 12/25/2015
@newacct:这或多或少是我想说清楚的。因为您只能更改对对象的引用或值。但此更改不会反映在调用方上。