# Passing functions to function by reference

- Thread: https://externals.io/message/22983
- Original archive: https://news-web.php.net/php.internals/22983
- Started by Brian Moon on 2006-04-26T22:35:57+00:00
- Messages: 8
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #22983 — Brian Moon — 2006-04-26T22:35:57+00:00

URL: https://externals.io/message/22983#22983

In PHP4, you could do:

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

$var = array_shift(test());

PHP 5.0 broke this.  There was a fatal error on the array_shift that 
only variables could be passed by reference.  There was a good argument 
for it.  So, we started migrating our code.

Well, seems this works in 5.1.  So, my question is, was it an 
intentional "fix" or will this break again and we need to continue to 
watch for this?

Brian.

---

## #22984 — Rasmus Lerdorf — 2006-04-26T22:41:26+00:00

URL: https://externals.io/message/22983#22984 · In reply to: #22983

Brian Moon wrote:
> In PHP4, you could do:
> 
> function test()
> {
>        return array(1,2,3);
> }
> 
> $var = array_shift(test());
> 
> PHP 5.0 broke this.  There was a fatal error on the array_shift that 
> only variables could be passed by reference.  There was a good argument 
> for it.  So, we started migrating our code.
> 
> Well, seems this works in 5.1.  So, my question is, was it an 
> intentional "fix" or will this break again and we need to continue to 
> watch for this?

In 5.1 this now throws an `E_STRICT` instead of a warning.  It is still a 
bad idea to pass a tempvar by reference, so yes, you should strive to 
write `E_STRICT` clean code.

-Rasmus

---

## #22985 — Jason Garber — 2006-04-27T01:00:40+00:00

URL: https://externals.io/message/22983#22985 · In reply to: #22984

Hello Rasmus,

RL> In 5.1 this now throws an `E_STRICT` instead of a warning.  It is still a
RL> bad idea to pass a tempvar by reference, so yes, you should strive to 
RL> write `E_STRICT` clean code.

At the possible expense of being blamed and flamed, I'll say it...

ifsetor($var, 'default') would go a long way to accommodate `E_STRICT` 
code.

-- 
Best regards,
 Jason                            mailto:jason@ionzoft.com

Wednesday, April 26, 2006, 6:41:26 PM, you wrote:

RL> Brian Moon wrote:
> > […]

RL> In 5.1 this now throws an `E_STRICT` instead of a warning.  It is still a
RL> bad idea to pass a tempvar by reference, so yes, you should strive to 
RL> write `E_STRICT` clean code.

RL> -Rasmus

---

## #22987 — Brian Moon — 2006-04-27T04:44:10+00:00

URL: https://externals.io/message/22983#22987 · In reply to: #22984

> In 5.1 this now throws an `E_STRICT` instead of a warning.  It is still a 
> bad idea to pass a tempvar by reference, so yes, you should strive to 
> write `E_STRICT` clean code.

Yeah, its more of a question of rewriting 6 years of PHP or not.  We 
were half way done when we upgraded the dev machines to 5.1.

Brian.

---

## #22997 — Brion Vibber — 2006-04-27T20:01:09+00:00

URL: https://externals.io/message/22983#22997 · In reply to: #22984

Rasmus Lerdorf wrote:
> > […]
> 
> In 5.1 this now throws an `E_STRICT` instead of a warning.  It is still a
> bad idea to pass a tempvar by reference, so yes, you should strive to
> write `E_STRICT` clean code.

Stupid question: why is it a bad idea?

I would expect these to be equivalent for all intents and purposes:

  func_taking_reference(some_func());

and

  $temp = some_func();
  func_taking_reference($temp);

where $temp is never used again and quickly passes out of scope.

Is there some reason that they are not considered equivalent, or that they
cannot or should not be made equivalent?

I seem to remember a reason being quoted for all these reference-related changes
something like it can cause memory corruption. But that would appear to be an
implementation bug, not an essential difficulty, as if it were really *memory
corruption* I can't imagine it being turned back on in 5.1. :)

-- brion vibber (brion @ pobox.com / brion @ wikimedia.org)

---

## #22998 — Petar Nedyalkov — 2006-04-27T20:27:56+00:00

URL: https://externals.io/message/22983#22998 · In reply to: #22997

> Rasmus Lerdorf wrote:
> > […]
>
> Stupid question: why is it a bad idea?

Check the mailing-list archive - there was a long discussion on this topic 
some 4, 5 months ago.

>
> I would expect these to be equivalent for all intents and purposes:
>
>   func_taking_reference(some_func());
>
> and
>
>   $temp = some_func();
>   func_taking_reference($temp);
>
> where $temp is never used again and quickly passes out of scope.
>
> Is there some reason that they are not considered equivalent, or that they
> cannot or should not be made equivalent?

Yes, of course :-) Nothing happens by chance here.

>
> I seem to remember a reason being quoted for all these reference-related
> changes something like it can cause memory corruption. But that would
> appear to be an implementation bug, not an essential difficulty, as if it
> were really *memory corruption* I can't imagine it being turned back on in
> 5.1. :)
>
> -- brion vibber (brion @ pobox.com / brion @ wikimedia.org)

-- 

Cyberly yours,
Petar Nedyalkov
Devoted Orbitel Fan :-)

PGP ID: 7AE45436
PGP Public Key: http://bu.orbitel.bg/pgp/bu.asc
PGP Fingerprint: 7923 8D52 B145 02E8 6F63 8BDA 2D3F 7C0B 7AE4 5436

---

## #22999 — Rasmus Lerdorf — 2006-04-27T21:24:55+00:00

URL: https://externals.io/message/22983#22999 · In reply to: #22997

Brion Vibber wrote:
> Rasmus Lerdorf wrote:
> > […]
> 
> Stupid question: why is it a bad idea?

Well, the original reason was because it caused weird and wonderful 
memory corruption in PHP 4.3.x, so if your code is ever going to run on 
that version you really need to not do that.

It also tends to be a bug.  Most functions that take an argument by 
reference do so for a reason.  There are of course exceptions to this as 
you have pointed out and in those cases assuming your code will never 
run under PHP 4.3.x it can be valid.  I would still say it is a better 
idea to something like:

   func_taking_reference($quiet=some_func());  // throw away ref mod

and document the fact that you are intentionally throwing away the 
reference modification that func_taking_reference is making.  That way 
you avoid the `E_STRICT` and make it very clear what you are doing.

You could make the same argument for using undefined variables.  Often 
that indicates a bug so the `E_NOTICE` can be really helpful, but other 
times it just gets in the way.  I don't think that means we should do 
away with the `E_NOTICE` on that and I also don't think it means you 
shouldn't try to write `E_NOTICE` clean code.

-Rasmus

---

## #23003 — Peter Brodersen — 2006-04-28T01:35:25+00:00

URL: https://externals.io/message/22983#23003 · In reply to: #22999

On Thu, 27 Apr 2006 17:24:55 -0400, in php.internals
rasmus@lerdorf.com (Rasmus Lerdorf) wrote:

>It also tends to be a bug.  Most functions that take an argument by 
>reference do so for a reason.  There are of course exceptions to this as 
>you have pointed out and in those cases assuming your code will never 
>run under PHP 4.3.x it can be valid.  I would still say it is a better 
>idea to something like:
>
>   func_taking_reference($quiet=some_func());  // throw away ref mod
>
>and document the fact that you are intentionally throwing away the 
>reference modification that func_taking_reference is making.  That way 
>you avoid the `E_STRICT` and make it very clear what you are doing.

It seems like a lot of these problems showed up because people used
 `array_shift()`, `array_pop()` or other such functions as a shortcut of
retrieving an element returned from a function.

I agree with the changes, but it still seems like people (mis)use
these functions because of lack of array operators (e.g.
array(2,4,3)[1] ).

I don't know if I would go that far to state that there is a demand
for such operators (and the discussion has been going on here before).
But if there is no (just as) simple way of doing it right users will
do it in a bad way.

-- 
- Peter Brodersen
