-3

Consider a simple function:

function pass(&$arr)
{
  // do something
}

If I call it like this…

$a = [1,2,3];
pass($a);

…this will work. However, if I do it like this,…

pass([1,2,3]);

…it will fail with the error Cannot pass parameter 1 by reference.

Why cant I get a reference to the temporary array in a function scope where the array is valid?

rhavin
  • 1,512
  • 1
  • 12
  • 33
  • 2
    What would you expect to happen ? Calling it like that doesn't make much sense as passing by ref implies you will change its value somehow in the function – exussum Oct 28 '21 at 19:33
  • @exussum yes, and you might even keep it in the class, but you probably dont need it outside anymore. Thats why you might use a temp array in those cases. Also, you might not want to rely on lazy copying, which is not language inherent but implementation inherent. – rhavin Oct 28 '21 at 19:35
  • 1
    Using `&` just means you pass the `zval` (where it points too) of the variable to the function. How would you re-call `[1,2,3]` without a stored variable? This makes no sense. – Jaquarh Oct 28 '21 at 19:54
  • @Jaquarh well, if you pass [1,2,3] to the function, it *has* to point somewhere, right? – rhavin Oct 28 '21 at 19:59
  • Revise some assembly, or C and it'll make more sense to you. – Jaquarh Oct 28 '21 at 20:00

3 Answers3

2

Well you can't do that ... as per php manual : Only variables should be passed by reference.

Though you can create a function that creates a variable in it's scope and then returns the reference (But again whats the point of passing it by reference when you are passing array directly ? I don't find any use of it or am I missing something ?)

function pass(&$arr)
{
  // do something
}


function &scopeVar($arr){
    return $arr;
}

pass(scopeVar([1, 2, 3]));

anees
  • 1,777
  • 3
  • 17
  • 26
  • You're missing easyness of usability: [1,2,3] *is* a variable, it just doesnt have a name. There are cases, where you need it outside afterwards, there are cases, where you just want to fire and forget. I was looking for an easy solution where I can have both. – rhavin Oct 28 '21 at 19:55
  • What References Are from the manual can give some insight into why they don't let you do this: https://www.php.net/manual/en/language.references.whatare.php "References in PHP are a means to access the same variable content by different names." If there's not a named memory location created in the calling scope, the function doesn't have the means to access the same variable content. This guy explained it really well: https://stackoverflow.com/questions/9848295/strict-standards-only-variables-should-be-passed-by-reference-error#comment47285711_9848317 – pumpkinthehead Oct 28 '21 at 20:05
  • 3
    More so, how do you store a value in memory and then reference it out of memory? Dur, who'd of thought - that is why we have variables and likewise the reason you can *pass by reference*. This guy is confused and this question should be closed. – Jaquarh Oct 28 '21 at 20:13
  • @rhavin there isn't going to be an easier solution for that ... you can create that function in a global scope and use whenever you want ... (for other cases as well.) – anees Oct 29 '21 at 21:54
1

@rhaven;

I have no clue what you are attempting to do here, but the error message is not only correct, it is meaningful. The array is created on-the-fly, and while it actually exists in memory, there are no references to it except the temporary one passed into the function.

Attempting to make a reference to an ephemeral value like this is an oxymoron. It simply makes zero sense.

@anees supplied an interesting workaround, but the bottom line is I believe you need to rethink the code, and why you either need:

  1. a temp variable in the call, or
  2. a reference in the function.
0

The [1,2,3] in the function call isn't a variable, it's just a hard coded value. You can pass that to a function that's pass by value, but not pass by reference. If the function is pass by reference it needs a variable. What's more, in PHP 7 they added a notice in strict standards if you try to declare the variable in the method call, i.e. pass(($a = [1,2,3]));: https://www.php.net/manual/en/migration70.incompatible.php

This page doesn't give a reason for the decision.

pumpkinthehead
  • 83
  • 2
  • 11