为啥在 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 &amp;y),或者通过指针传递你使用void foo(int *y)....还有另一种语言以同样的方式做这件事 【参考方案1】:

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

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 中通过引用传递?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们需要一个默认构造函数来在 C++ 中通过引用传递一个对象?

如何在php中通过引用传递无限参数[重复]

如何通过在 PHP 中通过引用传递变量来存储变量?

在python中通过引用传递引用

在C中通过引用传递数组?

在 C++ 中通过引用传递对象