用于解除引用函数结果的PHP语法

dre*_*mac 34 php arrays syntax function

背景

在我定期使用的每种其他编程语言中,操作函数的返回值很简单,而不会声明一个新变量来保存函数结果.

但是,在PHP中,这看起来并不那么简单:

example1(函数结果是一个数组)

<?php 
function foobar(){
    return preg_split('/\s+/', 'zero one two three four five');
}

// can php say "zero"?

/// print( foobar()[0] ); /// <-- nope
/// print( &foobar()[0] );     /// <-- nope
/// print( &foobar()->[0] );     /// <-- nope
/// print( "${foobar()}[0]" );    /// <-- nope
?>
Run Code Online (Sandbox Code Playgroud)

example2(函数结果是一个对象)

<?php    
function zoobar(){
  // NOTE: casting (object) Array() has other problems in PHP
  // see e.g., http://stackoverflow.com/questions/1869812
  $vout   = (object) Array('0'=>'zero','fname'=>'homer','lname'=>'simpson',);
  return $vout;
}

//  can php say "zero"?       
//  print zoobar()->0;         //  <- nope (parse error)      
//  print zoobar()->{0};       //  <- nope                    
//  print zoobar()->{'0'};     //  <- nope                    
//  $vtemp = zoobar();         //  does using a variable help?
//  print $vtemp->{0};         //  <- nope     
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议如何在PHP中执行此操作?

Óla*_*age 26

PHP无法访问函数的数组结果.有些人称这是一个问题,有些人只是接受这个语言的设计方式.所以PHP让你创建不必要的变量只是为了提取你需要的数据.

所以你需要这样做.

$var = foobar();
print($var[0]);
Run Code Online (Sandbox Code Playgroud)

  • @ÓlafurWaage,不,PHP不是这样设计的**.这是一种疏忽,而不是"只是语言的设计方式".正是因为这是一个问题,它在PHP 5.4中被修复**. (2认同)

sma*_*sey 20

这是特别是数组解除引用,目前在php5.3中不支持,但应该可以在下一个版本5.4中使用.另一方面,在当前的php版本中,对象解除引用是可能的.我也期待这个功能!

  • @dreftymac在PHP 7中,最终清理了这个,你现在可以在任何表达式中使用函数调用. (2认同)

Gor*_*don 17

从PHP 5.4开始,可以进行数组解除引用:

示例(来源):

function foo() {
    return array(1, 2, 3);
}
echo foo()[2]; // prints 3
Run Code Online (Sandbox Code Playgroud)

PHP 5.3你会得到

Parse error: syntax error, unexpected '[', expecting ',' or ';' 
Run Code Online (Sandbox Code Playgroud)

原答案:

这已经 已经 之前.答案是不.这不可能.

引用 安迪·古特曼斯在这个题目:

这是一个众所周知的功能请求,但在PHP 5.0中不受支持.我不能告诉你它是否会得到支持.这需要一些研究和很多想法.

您还可以找到这个要求 一些 的时间在PHP错误追踪系统.有关技术细节,我建议您查看官方RFC和/或询问PHP Internals.


Cal*_*vin 14

那么,您可以使用以下任何解决方案,具体取决于具体情况:

function foo() {
    return array("foo","bar","foobar","barfoo","tofu");
}
echo(array_shift(foo())); // prints "foo"
echo(array_pop(foo())); // prints "tofu"
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用list()从返回的数组中获取特定值:

list($foo, $bar) = foo();
echo($foo); // prints "foo"
echo($bar); // print "bar"
Run Code Online (Sandbox Code Playgroud)

编辑:我之前给出的每个()的示例代码都是错误的.each()返回一个键值对.所以使用foreach()可能更容易:

foreach(foo() as $key=>$val) {
    echo($val);
}
Run Code Online (Sandbox Code Playgroud)


Tyl*_*ter 7

不幸的是,没有办法做到这一点,尽管它在大多数其他编程语言中.

如果你真的想做一个衬里,你可以创建一个名为a()的函数并执行类似的操作

$test = a(func(), 1); // second parameter is the key.
Run Code Online (Sandbox Code Playgroud)

但除此之外,PHP中不支持func()[1].


Nol*_*lte 5

编写一个包装函数来实现同样的功能.由于PHP的简单类型转换,这可能是非常开放的:

function array_value ($array, $key) {
return $array[$key];
}
Run Code Online (Sandbox Code Playgroud)

  • 最有效的函数将在这里使用数组引用.示例:`function array_value(&$ a,$ k){$ b =&$ a; 返回$ b [$ k]; }` (2认同)

Ala*_*orm 5

正如其他人所说,这是不可能的.PHP的语法不允许它.但是,我确实有一个建议从另一个方向攻击问题.

如果您控制该getBarArray方法并可以访问PHP标准库(安装在许多PHP 5.2.X主机上并默认安装在PHP 5.3中),则应考虑返回ArrayObject而不是本机PHP数组/集合. ArrayObjects有一个offetGet方法,可以用来检索任何索引,所以你的代码可能看起来像

<?php
class Example {
    function getBarArray() {
        $array = new ArrayObject();
        $array[] = 'uno';
        $array->append('dos');
        $array->append('tres');
        return $array;
    }
}

$foo = new Example();
$value = $foo->getBarArray()->offsetGet(2);
Run Code Online (Sandbox Code Playgroud)

如果您需要本机数组/集合,您始终可以转换结果.

//if you need 
$array = (array) $foo->getBarArray();
Run Code Online (Sandbox Code Playgroud)

  • +1,我肯定会考虑到这一点.谢谢艾伦! (2认同)

Ant*_*oCS 5

如果您只想返回数组中的第一项,请使用current()函数.

return current($foo->getBarArray());
Run Code Online (Sandbox Code Playgroud)

http://php.net/manual/en/function.current.php