背景
在我定期使用的每种其他编程语言中,操作函数的返回值很简单,而不会声明一个新变量来保存函数结果。
然而,在PHP中,这似乎并不那么简单:
<?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
?>
<?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
有人可以建议如何在PHP中执行此操作吗?
答案 0 :(得分:25)
PHP无法访问函数的数组结果。有些人称这是一个问题,有些人只是接受这个语言的设计方式。所以PHP让你创建不必要的变量只是为了提取你需要的数据。
所以你需要这样做。
$var = foobar();
print($var[0]);
答案 1 :(得分:20)
这是特别是数组解除引用,目前在php5.3中不支持,但应该可以在下一个版本5.4中使用。另一方面,在当前的php版本中,对象解除引用是可能的。我也期待这个功能!
答案 2 :(得分:17)
从PHP 5.4起可以进行数组解除引用:
function foo() {
return array(1, 2, 3);
}
echo foo()[2]; // prints 3
PHP 5.3 你会得到
Parse error: syntax error, unexpected '[', expecting ',' or ';'
原始答案:
这是been asked already before。答案是不。这是不可能的。
关于此主题的quote Andi Gutmans:
这是众所周知的功能请求 但PHP 5.0不支持。一世 无法告诉你它是否曾经存在过 支持的。这需要一些研究 还有很多想法。
您还可以在PHP Bugtracker中找到此request a number of times。有关技术详情,建议您查看official RFC和/或询问PHP Internals。
答案 3 :(得分:14)
嗯,您可以根据具体情况使用以下任何一种解决方案:
function foo() {
return array("foo","bar","foobar","barfoo","tofu");
}
echo(array_shift(foo())); // prints "foo"
echo(array_pop(foo())); // prints "tofu"
或者您可以使用 list():
从返回的数组中获取特定值list($foo, $bar) = foo();
echo($foo); // prints "foo"
echo($bar); // print "bar"
编辑:我之前提供的 each()的示例代码不正确。 each()返回一个键值对。因此,使用 foreach():
可能更容易foreach(foo() as $key=>$val) {
echo($val);
}
答案 4 :(得分:7)
不幸的是,没有办法做到这一点,尽管它在大多数其他编程语言中。
如果你真的想做一个衬里,你可以创建一个名为a()的函数并执行类似
的操作$test = a(func(), 1); // second parameter is the key.
但除此之外,PHP中不支持func()[1]。
答案 5 :(得分:5)
编写一个完成相同操作的包装器函数。由于PHP的简单类型转换,这可能是非常开放的:
function array_value ($array, $key) {
return $array[$key];
}
答案 6 :(得分:5)
正如其他人所说,这是不可能的。 PHP的语法不允许它。但是,我确实有一个建议从另一个方向攻击问题。
如果您控制getBarArray
方法并且可以访问PHP标准库(安装在许多PHP 5.2.X主机上并默认安装在PHP 5.3中),您应该考虑返回{{1而不是本机PHP数组/集合。 ArrayObject
有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);
答案 7 :(得分:5)
如果您只想返回数组中的第一项,请使用current()函数。
return current($foo->getBarArray());
答案 8 :(得分:3)
您不能在PHP中链接这样的表达式,因此您必须将array_test()
的结果保存在变量中。
试试这个:
function array_test() {
return array(0, 1, 2);
}
$array = array_test();
echo $array[0];
答案 9 :(得分:3)
答案 10 :(得分:2)
非常贫民窟,但是,它只能使用PHP来完成。这利用了lambda函数(在PHP 5.3中引入)。看到并惊讶(并且,唉,害怕):
function foo() {
return array(
'bar' => 'baz',
'foo' => 'bar',
}
// prints 'baz'
echo call_user_func_array(function($a,$k) {
return $a[$k];
}, array(foo(),'bar'));
在大多数其他语言中,我们必须经历一些如此美好的事情。
为了记录,我做了类似于Nolte的事情。对不起,如果我让任何人的眼睛流血。
答案 11 :(得分:2)
这些是解决问题的一些方法。
首先,如果返回的变量数组不属于集合但每个变量具有不同的含义,则可以直接命名变量。
其他两种方法用于返回作为值集合的结果。
function test() {
return array(1, 2);
}
list($a, $b) = test();
echo "This should be 2: $b\n";
function test2() {
return new ArrayObject(array('a' => 1, 'b' => 2), ArrayObject::ARRAY_AS_PROPS);
}
$tmp2 = test2();
echo "This should be 2: $tmp2->b\n";
function test3() {
return (object) array('a' => 1, 'b' => 2);
}
$tmp3 = test3();
echo "This should be 2: $tmp3->b\n";
答案 12 :(得分:2)
我通常的解决方法是使用像这样的通用函数
function e($a, $key, $def = null) { return isset($a[$key]) ? $a[$key] : $def; }
然后
echo e(someFunc(), 'key');
作为奖励,当您不需要时,这也可以避免“未定义的索引”警告。
至于foo()[x]
不起作用的原因,答案是非常不礼貌的,不会在这里发表。 ;)
答案 13 :(得分:2)
当然,您可以返回一个对象而不是一个数组并以这种方式访问它:
echo "This should be 2: " . test()->b ."\n";
但是我没有找到用数组做这个的可能性:(
答案 14 :(得分:2)
经过进一步研究后,我认为答案是否定的,像这样的临时变量确实是处理函数返回的数组的规范方法。
看起来这将从PHP 5.4开始改变。
此外,这个答案最初是针对此版本的问题:
How to avoid temporary variables in PHP when using an array returned from a function
答案 15 :(得分:2)
这太牵强了,但如果你真的需要它在一条线上:
return index0( $foo->getBarArray() );
/* ... */
function index0( $some_array )
{
return $some_array[0];
}
答案 16 :(得分:1)
简答:
是。只要函数结果和PHP的特定版本支持PHP,就可以对PHP中函数的返回值进行操作。
引用example2:
// can php say "homer"?
// print zoobar()->fname; // homer <-- yup
案例:
答案 17 :(得分:1)
以前在PHP 5.3中你必须这样做:
function returnArray() {
return array(1, 2, 3);
}
$tmp = returnArray();
$ssecondElement = $tmp[1];
结果:2
从PHP 5.4开始,可以按如下方式取消引用数组:
function returnArray() {
return array(1, 2, 3);
}
$secondElement = returnArray()[1];
结果:2
从PHP 5.5开始:
你甚至可以变得聪明:
echo [1, 2, 3][1];
结果:2
您也可以对字符串执行相同的操作。它被称为字符串解除引用:
echo 'PHP'[1];
结果:H
答案 18 :(得分:1)
有三种方法可以做同样的事情:
正如Chacha102所说,使用函数返回索引值:
function get($from, $id){
return $from[$id];
}
然后,您可以使用:
get($foo->getBarArray(),0);
获取第一个元素,依此类推。
使用current和array_slice的懒惰方式:
$first = current(array_slice($foo->getBarArray(),0,1));
$second = current(array_slice($foo->getBarArray(),1,1));
使用相同的函数返回数组和值:
class FooClass {
function getBarArray($id = NULL) {
$array = array();
// Do something to get $array contents
if(is_null($id))
return $array;
else
return $array[$id];
}
}
然后你可以获得整个数组和一个数组项。
$array = $foo->getBarArray();
或
$first_item = $foo->getBarArray(0);
答案 19 :(得分:1)
如果它只是美学,那么如果你返回一个对象,Object符号将会起作用。就内存管理而言,如果没有临时副本,只需更改引用。
答案 20 :(得分:0)
您可以使用参考:
$ref =& myFunc();
echo $ref['foo'];
这样,你实际上并没有创建返回数组的副本。
答案 21 :(得分:0)
这有用吗?
return ($foo->getBarArray())[0];
否则,你可以发布getBarArray()函数吗?我不明白为什么到目前为止你发布的内容不起作用。