PHP syntax for dereferencing function result

19,138

Solution 1

This is specifically array dereferencing, which is currently unsupported in php5.3 but should be possible in the next release, 5.4. Object dereferencing is on the other hand possible in current php releases. I'm also looking forward to this functionality!

Solution 2

PHP can not access array results from a function. Some people call this an issue, some just accept this as how the language is designed. So PHP makes you create unessential variables just to extract the data you need.

So you need to do.

$var = foobar();
print($var[0]);

Solution 3

Array Dereferencing is possible as of PHP 5.4:

Example (source):

function foo() {
    return array(1, 2, 3);
}
echo foo()[2]; // prints 3

with PHP 5.3 you'd get

Parse error: syntax error, unexpected '[', expecting ',' or ';' 

Original Answer:

This has been been asked already before. The answer is no. It is not possible.

To quote Andi Gutmans on this topic:

This is a well known feature request but won't be supported in PHP 5.0. I can't tell you if it'll ever be supported. It requires some research and a lot of thought.

You can also find this request a number of times in the PHP Bugtracker. For technical details, I suggest you check the official RFC and/or ask on PHP Internals.

Solution 4

Well, you could use any of the following solutions, depending on the situation:

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

Or you can grab specific values from the returned array using list():

list($foo, $bar) = foo();
echo($foo); // prints "foo"
echo($bar); // print "bar"

Edit: the example code for each() I gave earlier was incorrect. each() returns a key-value pair. So it might be easier to use foreach():

foreach(foo() as $key=>$val) {
    echo($val);
}

Solution 5

There isn't a way to do that unfortunately, although it is in most other programming languages.

If you really wanted to do a one liner, you could make a function called a() and do something like

$test = a(func(), 1); // second parameter is the key.

But other than that, func()[1] is not supported in PHP.

Share:
19,138
dreftymac
Author by

dreftymac

Greetings! Ask and answer. Share alike.

Updated on June 13, 2022

Comments

  • dreftymac
    dreftymac almost 2 years

    Background

    In every other programming language I use on a regular basis, it is simple to operate on the return value of a function without declaring a new variable to hold the function result.

    In PHP, however, this does not appear to be so simple:

    example1 (function result is an array)

    <?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
    ?>
    

    example2 (function result is an object)

    <?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     
    
  • Sikshya Maharjan
    Sikshya Maharjan about 15 years
    I realise that I'm still incredibly new to this, but why is this a problem? It...makes sense to me that you'd need to create a variable to hold a value/result; though admittedly: very new
  • Ólafur Waage
    Ólafur Waage about 15 years
    Some people call this an issue, but this is just how the language is designed. Other languages are designed in a way where this is possible, and people coming from those languages feel that this is an issue.
  • Lordn__n
    Lordn__n about 15 years
    I honestly don't know why this is the case but it is.
  • Sikshya Maharjan
    Sikshya Maharjan about 15 years
    Thanks for the clarity @ Ólafur =)
  • dreftymac
    dreftymac about 15 years
    It's an issue because it becomes very easy to lose track of where you are if you have a function that returns a structured variable or object. For example, what if you have $data['tvshow']['episodes'][1]['description'] as a valid address in your variable?
  • vartec
    vartec about 15 years
    @ricebowl: no, it doesn't make sense. It would make sens to have for example $gdver = gd_info()["GD Version"]. The problem is, that PHP is not object oriented.
  • vartec
    vartec about 15 years
    @Ólafur: actually I don't think there is other language which would have similar "feature". AFAIR, even in plain C you can dereference function result. +1 anyway, because that's the only correct answer.
  • user5880801
    user5880801 about 15 years
    @vartec, what array dereferencing has to do with OOP?
  • James Skidmore
    James Skidmore almost 15 years
    No that doesn't work either. Regardless of the function, it throws an "unexpected [" error.
  • thedz
    thedz almost 15 years
    Oh wow, I didn't know that. Do you know why that doesn't work? Shouldn't func() be essentially an array type with the return value, so [1] acts on an array? Or does PHP parse it poorly?
  • rpiaggio
    rpiaggio almost 15 years
    PHP does not parse it like other languages do, so you have to define it as a variable first.
  • Ben Dunlap
    Ben Dunlap over 14 years
    Do you ever happen to find yourself looking at code that uses this technique, and wondering (even if just for a few milliseconds), "Now what does this do again?"
  • outis
    outis over 14 years
    This still creates a temporary (2 or 3, in fact), but they're in a lower scope an quickly go away, so that's a bonus.
  • dreeves
    dreeves over 14 years
    Wow, nice work finding all those other versions of this question. I did look first, which, per the stackoverflow creators, means it's worth having another version of the question, to make it more googlable.
  • James
    James over 13 years
    @Kouroki Kaze: array_slice still returns an array, even if the slice would result in a single value. You could combine it with current, but that's starting to get a bit long for a single line. ;-)
  • KyleFarris
    KyleFarris about 13 years
    The most efficient function would use an array reference here. Example: function array_value(&$a,$k) { $b = &$a; return $b[$k]; }
  • Nolte
    Nolte almost 13 years
    I think you can get the same result by just telling the function to return by reference, i.e. function &array_value (...
  • Admin
    Admin over 11 years
    Really, the language seems consistent on allowing fluent usage of results, so why not with arrays? Seems like they agreed.
  • Zsolt Gyöngyösi
    Zsolt Gyöngyösi about 10 years
    In PHP 5.5.10 it still throws the following error: "Strict standards: Only variables should be passed by reference in php". Ridiculous.
  • dreftymac
    dreftymac about 9 years
    NOTE: This question was incorrectly marked as "already asked" array dereferencing. This question has not already been asked, because it is not exclusively about arrays. A PHP function can return any value type, not just arrays (see example2 in the original post, where the function result is an object, and not an array).
  • dreftymac
    dreftymac almost 9 years
    NOTE: This question was incorrectly marked as a duplicate of array dereferencing. This question is not a duplicate, because it is not exclusively about arrays. A PHP function can return any value type, not just arrays (see example2 in the original post, where the function result is an object, and not an array).
  • Pacerier
    Pacerier almost 9 years
    @ÓlafurWaage, No, PHP is not designed this way. This is an oversight and not "just how the language is designed". It is precisely because this is an issue that it is fixed in PHP 5.4.
  • Pacerier
    Pacerier almost 9 years
    @ZsoltGyöngyösi, That error is present way back in PHP 5.05. See 3v4l.org/voQIS . Also, performance note: array_pop may be fast because you need to simply remove the last element, but array_shift is incredibly slow because it needs to change all the number indexes by shifting them down by 1.
  • Pacerier
    Pacerier almost 9 years
    @BenDunlap, It's blackboxed. So it's the method name that counts.
  • Pacerier
    Pacerier almost 9 years
    @user187291, Why do you say "the answer is quite impolite"?
  • Pacerier
    Pacerier almost 9 years
    There are 28 answers here. Visitors to this page will thank you if you can delete this answer so we have more signal and less noise.
  • Pacerier
    Pacerier almost 9 years
    This is a comment, not an answer. There are 28 answers here. Visitors to this page will thank you if you can convert this answer to a comment.
  • Pacerier
    Pacerier almost 9 years
    @James, It's long, but that's not the point. It's still one line and it works.
  • Pacerier
    Pacerier almost 9 years
    current(array_slice($arr, $offset, 1)) is good. Because the new array has just been created and there are no leaking variable references to it, current is guaranteed (by the specs) to point to the first element without the need to call reset.
  • Pacerier
    Pacerier almost 9 years
    There are 28 answers here. Visitors to this page will thank you if you can delete this answer (actually, this is not even an answer) so we have more signal and less noise.
  • Pacerier
    Pacerier almost 9 years
    call_user_func alone will work: 3v4l.org/qIbtp. We don't need call_user_func_array. Btw, "ghetto" mean many things... what would "ghetto" mean here?
  • Pacerier
    Pacerier almost 9 years
    @KyleFarris, I highly doubt that is more efficient now, nor even in the future. (There're also test results here.) This is because 1) using array references when none is needed has been discouraged by language prescriptivists, and 2) current and future language implementors try to optimize general use cases, most of which are derived from such prescriptions.
  • Pacerier
    Pacerier almost 9 years
    No, there is no guarantee that current is currently pointing to the first element. See 3v4l.org/OZLjR and 3v4l.org/kEC9H for examples whereby blindly calling current will indeed give you the non-first item. Whenever you call current you must first call reset, otherwise be prepared for trouble.
  • KyleFarris
    KyleFarris almost 9 years
    Man, that was like 4.5 years ago. Who know what I was thinking then? Probably just meant something like "put together with ducktape and string".
  • Andrea
    Andrea over 8 years
    @dreftymac In PHP 7 this was cleaned up finally and you can now use a function call in any expression.
  • pbarney
    pbarney over 2 years
    Been working with PHP for a long time and I didn't realize until now that echo [1, 2, 3][1] was a thing. Thanks for the education, friend!