一个函数的多次返回


198

是否有可能具有两个返回的函数,如下所示:

function test($testvar)
{
  // Do something

  return $var1;
  return $var2;
}

如果是这样,我如何才能分别获得每份退货?


1
您到底想完成什么?当然,如果您解释了真正的问题,那么这里的人可以帮助您找到一个优雅的解决方案。
Mike Daniels 2010年

3
问题不能区分两个值中的一个或两个值,两个值中的两个,也不能区分新概念懒惰评估,然后可能是两个值中的两个。第一个对于任何类型的条件流都是微不足道的。python中允许使用第二个:q,r = divmod(x,y); 以及Lisp;PHP需要list($ q,$ r)= twovals(); hack,其中函数twovals(){返回array($ a,$ b); }。惰性评估相当先进,尚未在PHP中流行。由于问题不精确,建议不要将此条目用作该主题的权威参考。
DragonLord 2012年

5
如果您需要这两个值,请在数组中返回它们。
Bhargav Nanekalva 2015年

2
@DragonLord在PHP 7.1中,您可以使用简短列表语法
Janus Troelsen

1
这里有一个重复的问题,但是答案更加简洁,因此可以使您更快地了解问题:从一个函数返回2个值
Gras Double

Answers:


162

无法返回两个变量。虽然,您可以传播一个数组并返回它;创建条件以返回动态变量,等等。

例如,此函数将返回 $var2

function wtf($blahblah = true) {
    $var1 = "ONe";
    $var2 = "tWo";

    if($blahblah === true) {
      return $var2;
    }
    return $var1;
}

在应用中:

echo wtf();
//would echo: tWo
echo wtf("not true, this is false");
//would echo: ONe

如果您都想要它们,可以稍微修改一下功能

function wtf($blahblah = true) {
    $var1 = "ONe";
    $var2 = "tWo";

    if($blahblah === true) {
      return $var2;
    }

    if($blahblah == "both") {
      return array($var1, $var2);
    }

    return $var1;
}

echo wtf("both")[0]
//would echo: ONe
echo wtf("both")[1]
//would echo: tWo

list($first, $second) = wtf("both")
// value of $first would be $var1, value of $second would be $var2

15
如果只有PHP有Perlwantarray()
Marc B 2010年

6
恕我直言,如果省略了第一部分,该答案将得到改善,该部分讨论了如何根据某些条件返回一个另一个值。我敢肯定,参加本次讨论的99.999%以上的人都想知道如何同时返回两个值。查看投票最高的答案。
ToolmakerSteve

401

从技术上讲,您不能返回多个值。但是,有多种方法可以解决该限制。最类似于返回多个值的方式是使用list关键字:

function getXYZ()
{
    return array(4,5,6);
}

list($x,$y,$z) = getXYZ();

// Afterwards: $x == 4 && $y == 5 && $z == 6
// (This will hold for all samples unless otherwise noted)

从技术上讲,您将返回一个数组,并使用list该数组的元素以不同的值存储,而不是存储实际的数组。使用此技术会使用户感觉最像返回多个值。

list解决方案是一个特定于php 的解决方案。有几种语言具有相似的结构,但是更多的语言则没有。通常有另一种“返回”多个值的方法,它几乎可以在每种语言中使用(一种或另一种方式)。但是,此方法看起来会大不相同,因此可能需要一些习惯。

// note that I named the arguments $a, $b and $c to show that
// they don't need to be named $x, $y and $z
function getXYZ(&$a, &$b, &$c)
{
    $a = 4;
    $b = 5;
    $c = 6; 
}

getXYZ($x, $y, $z);

此技术还用于php本身定义的某些函数中(例如,$countstr_replace中$matchespreg_match中)。这可能与返回多个值完全不同,但是至少值得了解。

第三种方法是使用对象保存所需的不同值。这是更多类型的输入,因此它的使用频率不如上述两种方法。但是,当在多个位置使用相同的变量集时(或者,当然,使用不支持上述方法的语言或允许您无需额外输入即可执行此操作的语言),可以使用此方法。

class MyXYZ
{
    public $x;
    public $y;
    public $z;
}

function getXYZ()
{
    $out = new MyXYZ();

    $out->x = 4;
    $out->y = 5;
    $out->z = 6;

    return $out;
}

$xyz = getXYZ();

$x = $xyz->x;
$y = $xyz->y;
$z = $xyz->z;

上面的方法总结了从函数返回多个值的主要方法。但是,这些方法有所不同。要看的最有趣的变体是实际上返回数组的那些变体,仅因为在PHP中可以对数组做很多事情。

首先,我们可以简单地返回一个数组,而不将其视为数组以外的任何东西:

function getXYZ()
{
    return array(1,2,3);
}

$array = getXYZ();

$x = $array[1];
$y = $array[2];
$z = $array[3];

关于上面的代码,最有趣的部分是函数中的代码与我提供的第一个示例相同;只有调用该函数的代码已更改。这意味着取决于调用函数如何处理函数返回的结果。

或者,可以使用关联数组:

function getXYZ()
{
    return array('x' => 4,
                 'y' => 5,
                 'z' => 6);
}

$array = getXYZ();

$x = $array['x'];
$y = $array['y'];
$z = $array['z'];

PHP确实具有compact允许您执行与上述相同的功能,但同时减少了编写代码的功能。(嗯,该示例将不会有更少的代码,但是实际应用程序中可能会有。)但是,我认为节省类型输入的数量很少,并且使代码难以阅读,所以我自己不会这样做。不过,这是一个示例:

function getXYZ()
{
    $x = 4;
    $y = 5;
    $z = 6;

    return compact('x', 'y', 'z');
}

$array = getXYZ();

$x = $array['x'];
$y = $array['y'];
$z = $array['z'];

应当指出,虽然compactextract可以在调用代码中使用,但是由于使用它是一个坏主意(尤其是对于这样简单的事情),我什至不会给出示例。问题在于它会“神奇”地为您创建变量,而您无需查看代码的其他部分就看不到创建了哪些变量。

最后,我想提一下,list在关联数组中并不能很好地发挥作用。以下将满足您的期望:

function getXYZ()
{
    return array('x' => 4,
                 'y' => 5,
                 'z' => 6);
}

$array = getXYZ();

list($x, $y, $z) = getXYZ();

但是,以下操作会有所不同:

function getXYZ()
{
    return array('x' => 4,
                 'z' => 6,
                 'y' => 5);
}

$array = getXYZ();

list($x, $y, $z) = getXYZ();

// Pay attention: $y == 6 && $z == 5

如果您使用list了关联数组,并且将来有人不得不在被调用函数中更改代码(这可能在任何情况下都可能发生),它可能会突然中断,因此我建议您不要list与关联数组结合使用。


2
同样:return compact('var1','var2','var3');
bjudson

1
那是另一种选择,但是对我来说,返回多个值就像返回数组一样。不过那可能只是我。就个人而言,我会找到return array('x' => $x, 'y' => $y, 'z' => $z)更干净的东西,但是到我自己写的时候,而不是我要别人使用这种格式的时候。
贾斯珀,2010年

2
使用List()是我遇到的类似问题的好答案。这是验证并将多个变量返回到函数中的绝佳方法。快速浏览php文档将为该功能提供更多的信息,并且可能使其更加清晰。php.net/manual/en/function.list.php ..谢谢Jasper!
JustinP '10 -10-19

2
+1代表如此广泛的答案,尤其是针对如此广泛的一般性问题。尽管如此,这个答案还是极大地帮助了我。
Lee Blake

2
@Mikey的历史原因。该答案最初发布在另一个问题上,由于与该问题完全相同而被删除(尽管它实际上更老了)。答案移到了这个问题之后,才提出这个问题。
贾斯珀(Jasper)

73

在您的示例中,第二个返回将永远不会发生-第一个返回是PHP将运行的最后一件事。如果需要返回多个值,请返回一个数组:

function test($testvar) {

    return array($var1, $var2);
}

$result = test($testvar);
echo $result[0]; // $var1
echo $result[1]; // $var2

18
您还可以执行以下操作:list($result_1, result_2) = test($testvar);
Tim Cooper 2010年

@蒂姆·库珀:result_2还是$result_2
彼得·莫滕森

@PeterMortensen:$result_2
蒂姆·库珀

46

从PHP 7.1开始,我们对列表进行了适当的解构。因此,您可以执行以下操作:

$test = [1, 2, 3, 4];
[$a, $b, $c, $d] = $test;
echo($a);
> 1
echo($d);
> 4

在一个函数中,它看起来像这样:

function multiple_return() {
    return ['this', 'is', 'a', 'test'];
}

[$first, $second, $third, $fourth] = multiple_return();
echo($first);
> this
echo($fourth);
> test

销毁是一个非常强大的工具。它也能够解构key => value对:

["a" => $a, "b" => $b, "c" => $c] = ["a" => 1, "b" => 2, "c" => 3];

看一下PHP 7.1的新功能页面:

新功能


5
我希望即使问题创建时尚未接受StackOverflow之类的功能,例如“功能性答案”,因为此处的答案非常有用且已更新,但这当然是题外话了。
Jonatas CD

3
@JonatasCD-不知道为什么您说这个答案是“题外话”。在php 7.1中,这从函数创建和处理多个返回值的最便捷方法。因此,对于较新的php版本,它是原始接受答案的绝佳答案。
ToolmakerSteve

@ToolmakerSteve我想你误解了我。我对这个问题的“偏离主题”是我的建议,就是能够根据将来的实现方式更改被接受的问题。这完全
符合

@JonatasCD-解释了。(这不是我的答案,只是让我感到困惑。)至少一个标签上写着“这比接受的答案更新得多”,也许三个人必须同意该标签,然后它才能成为特色。:)
ToolmakerSteve

26

在PHP 5.5中,还有一个新概念:generators,您可以从一个函数中产生多个值:

function hasMultipleValues() {
    yield "value1";
    yield "value2";
}

$values = hasMultipleValues();
foreach ($values as $val) {
    // $val will first be "value1" then "value2"
}

16

或者您可以通过引用传递:

function byRef($x, &$a, &$b)
{
    $a = 10 * $x;
    $b = 100 * $x;
}

$a = 0;
$b = 0;

byRef(10, $a, $b);

echo $a . "\n";
echo $b;

这将输出

100
1000

9

我知道我来晚了,但是有一个很好而简单的解决方案。
可以使用解构一次返回多个值。

function test()
{
    return [ 'model' => 'someValue' , 'data' => 'someothervalue'];
}

现在你可以使用这个

$result = test();
extract($result);

extract为数组中的每个成员创建一个变量,以该成员命名。因此,您现在可以访问$model$data


1
注意:请注意,键(此处modeldata)尚未作为变量存在。如果这样,请使用prefix参数extract以避免冲突。
ToolmakerSteve

7

您可以从一个函数返回多个数组和标量

function x()
{
    $a=array("a","b","c");
    $b=array("e","f");
    return array('x',$a,$b);
}

list ($m,$n,$o)=x();

echo $m."\n";
print_r($n);
print_r($o);

7

它不可能有两个return语句。但是它不会引发错误,但是在调用函数时,您只会收到第一个return语句值。我们可以使用数组的return来获取多个值。例如:

function test($testvar)
{
  // do something
  //just assigning a string for example, we can assign any operation result
  $var1 = "result1";
  $var2 = "result2";
  return array('value1' => $var1, 'value2' => $var2);
}

5

根据定义,函数仅返回一个值。

但是,正如您假设的那样,该值可以是一个数组。

因此,您当然可以执行以下操作:

<?PHP
function myfunc($a,$b){
   return array('foo'=>$a,'bar'=>$b);
}
print_r(myfunc('baz','bork'));

也就是说,值得花点时间考虑一下您要解决的问题。虽然返回一个复杂的结果值(如数组或对象)是完全有效的,但如果您想的是“我想返回两个值”,则可能设计得很差。如果您的问题中没有更多细节,这很难说,但是停下来三思而后行也不会有任何伤害。


5

最佳实践是将返回的变量放入数组,然后用于list()将数组值分配给变量。

<?php

function add_subt($val1, $val2) {
    $add = $val1 + $val2;
    $subt = $val1 - $val2;

    return array($add, $subt);
}

list($add_result, $subt_result) = add_subt(20, 7);
echo "Add: " . $add_result . '<br />';
echo "Subtract: " . $subt_result . '<br />';

?>

5

是的,您可以使用一个对象:-)

但是最简单的方法是返回一个数组:

return array('value1', 'value2', 'value3', '...');

5

对于PHP 7.1 <=,您可以使用新语法(而不是list函数):

/**
* @return  array  [foo, bar]
*/
function getFooAndBar(): array {
    return ['foo', 'bar'];
}

[$foo, $bar] = getFooAndBar();

print 'Hello '. $foo . ' and ' . $bar;

如果您要返回2-3个变量,对我来说就可以了,否则应该使用具有所需属性的对象。


4

我已经为多个返回值PHP函数实现了这样的实现。对您的代码好。谢谢。

 <?php
    function multi_retun($aa)
    {
        return array(1,3,$aa);
    }
    list($one,$two,$three)=multi_retun(55);
    echo $one;
    echo $two;
    echo $three;
    ?>

4

上面绿色勾号给出的答案实际上是错误的。如果返回数组,则可以在PHP中返回多个值。有关示例,请参见以下代码:

<?php

function small_numbers()
{
    return array (0, 1, 2);
}

list ($zero, $one, $two) = small_numbers();

该代码实际上是从PHP网站的以下页面复制的:http : //php.net/manual/en/functions.returning-values.php 我本人也多次使用相同的代码,因此可以确认很好,而且有效。


该答案涉及问题中的代码示例,因此它并不是严格错误的。但是这个问题是模棱两可的。这样做的目的可能从一个函数调用返回两个值。
彼得·莫滕森

3

PHP中的函数只能返回一个变量。您可以使用具有全局作用域的变量,可以返回数组,也可以通过引用该函数来传递变量,而不是更改值,但是所有这些都会降低代码的可读性。我建议您研究一下这些课程。


3

我以为我会进一步说明上面的一些回答。

class nameCheck{

public $name;

public function __construct(){
    $this->name = $name;
}

function firstName(){
            // If a name has been entered..
    if(!empty($this->name)){
        $name = $this->name;
        $errflag = false;
                    // Return a array with both the name and errflag
        return array($name, $errflag);
            // If its empty..
    }else if(empty($this->name)){
        $errmsg = 'Please enter a name.';
        $errflag = true;
                    // Return both the Error message and Flag
        return array($errmsg, $errflag);
    }
}

}


if($_POST['submit']){

$a = new nameCheck;
$a->name = $_POST['name'];
//  Assign a list of variables from the firstName function
list($name, $err) = $a->firstName();

// Display the values..
echo 'Name: ' . $name;
echo 'Errflag: ' . $err;
}

?>
<form method="post" action="<?php $_SERVER['PHP_SELF']; ?>" >
<input name="name"  />
<input type="submit" name="submit" value="submit" />
</form>

提交后,这将为您提供一个输入字段和一个提交按钮,如果名称输入字段为空,则会返回错误标志和一条消息。如果名称字段具有值,它将返回值/名称和错误标志0(错误=无错误)。希望这可以帮助!


3

有些人可能更喜欢返回多个值作为对象:

function test() {
    $object = new stdClass();

    $object->x = 'value 1';
    $object->y = 'value 2';

    return $object;
}

并这样称呼它:

echo test()->x;

要么:

$test = test();
echo $test->y;

3

是的,没有。您不能返回多个变量/对象,但是如您建议的那样,您可以将它们放入数组并返回。

数组的嵌套没有限制,因此您可以将其打包返回。


2

您始终只能返回一个可能是数组的变量。但是您可以从函数内部更改全局变量。多数情况下,那不是很好的风格,但确实有效。在类中,通常从函数内部更改类可变量而不返回它们。


1

答案是不。当解析器到达第一个return语句时,它将控制权返回给调用函数-您的第二个return语句将永远不会执行。


严格来说,是的。但是这个问题是模棱两可的。可能的目的是从一个函数调用中返回两个值。
彼得·莫滕森

1

将所有变量添加到数组中,然后最后返回array

function test($testvar)
{
  // do something
  return array("var1" => $var1, "var2" => @var2);
}

然后

$myTest = test($myTestVar);
//$myTest["var1"] and $myTest["var2"] will be usable

1

我认为eliego已经清楚地解释了答案。但是,如果要返回两个值,请将它们放入数组中并返回。

function test($testvar)
{
  // do something

  return array('var1'=>$var1,'var2'=>$var2);
//defining a key would be better some times   
}

//访问返回值

$returned_values = test($testvar);

echo $returned_values['var1'];
echo $returned_values['var2'];

写这篇文章时您清醒吗?我一眼就能发现两个错误。1)您使用$this关键字,但没有提及类或对象。2)如果将值返回到变量中$returned_values,则应从该变量中回显:echo $returned_values['var1'];
dading84 '17

解决了这个问题。
Gihan De Silva,

0
<?php
function foo(){
  $you = 5;
  $me = 10;
  return $you;
  return $me;
}

echo foo();
//output is just 5 alone so we cant get second one it only retuns first one so better go with array


function goo(){
  $you = 5;
  $me = 10;
  return $you_and_me =  array($you,$me);
}

var_dump(goo()); // var_dump result is array(2) { [0]=> int(5) [1]=> int(10) } i think thats fine enough

?>

0

允许多次返回的语言通常只会将多个值转换为数据结构。

例如,在Python中,您可以返回多个值。但是,它们实际上只是作为一个元组返回的。

因此,您可以通过创建一个简单的数组并将其返回来在PHP中返回多个值。


0

您可以通过引用设置两个或多个变量的值:

function t(&$a, &$b) {
    $a = 1;
    $b = 2;
}


t($a, $b);

echo $a . '  ' . $b;

输出:

1 2

关于“获取两个或多个变量的值”:您是说“返回两个或多个变量的值”吗?
彼得·莫滕森

0

PHP是否仍使用“输出参数”?如果是这样,则可以使用语法来修改函数中使用的一个或多个参数。函数返回后,您将可以自由使用修改后的变量。


-1

这是最简单的方法:

public function selectAllUsersByRole($userRole, $selector) {

    $this->userRole = $userLevel;
    $this->selector = $selector;

    $sql = "SELECT * FROM users WHERE role <= ? AND del_stat = 0";
    $stm = $this->connect()->prepare($sql); // Connect function in Dbh connect to database file
    $stm->execute([$this->userRole]); // This is PHP 7. Use array($this->userRole) for PHP 5

    $usersIdArray = array();
    $usersFNameArray = array();
    $usersLNameArray = array();

    if($stm->rowCount()) {
        while($row = $stm->fetch()) {

            array_push($usersIdArray,    $row['id']);
            array_push($usersFNameArray, $row['f_name']);
            array_push($usersLNameArray, $row['l_name']);

            // You can return only $row['id'] or f_name or ...
            // I used the array because it's most used.
        }
    }
    if($this->selector == 1) {
        return $usersIdArray;
    }elseif($this->selector == 2) {
        return $usersFNameArray;
    }elseif($this->selector == 3) {
        return $usersLNameArray;
    }

}

我们怎么称呼这个功能?

$idData = $selectAllUsers->selectAllUsersByLevel($userRole, 0);
print_r($idData);
$idFName = $selectAllUsers->selectAllUsersByLevel($userRole, 1);
print_r($idFname);

而已。好简单。


-1
$var1 = 0;
$var2 = 0;

function test($testvar, &$var1 , &$var2)
{
  $var1 = 1;
  $var2 = 2;
  return;
}
test("", $var1, $var2);

// var1 = 1, var2 = 2 

这不是一个好方法,但是我认为我们可以同时在一个函数中设置两个变量。


-4

我有一个类似的问题-所以我尝试了一下,然后用google搜索了一下(找到了这个线程)。经过5分钟的尝试和错误后,我发现您可以简单地使用“ AND”在一行返回中返回两个(也许更多-尚未测试)。

我的代码:

  function get_id(){
    global $b_id, $f_id;
    // stuff happens
    return $b_id AND $f_id;
  }
  //later in the code:
  get_id();
  var_dump($b_id);
  var_dump($f_id); // tested output by var_dump

有用。我得到了我期望/应该获得的两个价值。我希望我可以帮助任何人阅读此主题:)


3
这是不正确的。“ AND”只是一个布尔运算符,因此您的函数实际上返回一个布尔值。它似乎起作用的唯一原因是因为您将$ b_id和$ f_id声明为全局变量。完全删除“ AND”和return语句,您将看到结果保持不变。
马特·样式

这是非常令人误解的,因为您声明了$ b_id和$ f_id全局,因此可以在任何上下文中使用。
paulus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.