tags:

views:

1882

answers:

5

I'm trying to reduce the warnings that are sent to my apache server log.

One warning is:

Call-time pass-by-reference has been deprecated.

It is hard for me to imagine why this was deprecated since it is such a useful programming feature, basically I do this:

public function takeScriptsWithMarker(&$lines, $marker) {

 ...
}

and I call this function repeatedly getting results back from it and processing them but also letting the array $lines build up by being sent into this method repeatedly.

  1. To reprogram this would be extensive.
  2. I don't want to just "turn off warnings" since I want to see other warnings.

So, as call-by-reference is deprecated, what is the "accepted way" to attain the functionality of this pattern: namely of sending an array of strings into a method, have them be changed by the method, then continuing to use that array?

+15  A: 

Actually, there's no problem with the way you define the function. Is a problem with the way you call the function. So for your example, instead of calling it like:

takeScriptsWithMarker(&$lines, $marker);

You'd call it like:

takeScriptsWithMarker($lines, $marker); // no ampersands :)

So the feature is still available. But I don't know the reason behind this change.

Ionuț G. Stan
that simple change worked nicely, thanks
Edward Tanguay
"I don't know the reason behind this change.". Long story short, the *function* is in charge of deciding what is passed by reference, not the *caller*. When the caller can pass any arbitrary argument by reference, that may result in side effects that the function's author wasn't prepared for.
Frank Farmer
From the docs for allow_call_time_pass_reference: "Passing arguments by reference at function call time was deprecated for code cleanliness reason. Function can modify its argument in undocumented way if it didn't declared that the argument is passed by reference. To prevent side-effects it's better to specify which arguments are passed by reference in function declaration only."
Frank Farmer
@Frank, thanks for the clarifications. The bad part is that, just looking at a function call, you have no idea that any of those arguments may be passed by reference. So, you may get side effects in the function without knowing it. A requirement to have ampersands both in function definition and function call would have been much better in my opinion.
Ionuț G. Stan
Adriano Varoli Piazza
@Adriano, yes, but I'm also thinking about situations in which the name of the function conveys pretty well its intent, so I don't feel a need to look up the function definition. Furthermore, the return value of the function may be correct, so no reason to look up the function definition... in the beginning at least.
Ionuț G. Stan
+1  A: 

You can set allow_call_time_pass_reference to true in your php.ini file. But it's a hack.

Otto Allmendinger
A: 

You could pass in the array, let it manipulate it, and then "return" it, instead of messing with the original reference. It shouldn't be too hard to just include a return and assignment.

public function takeScriptsWithMarker($lines, $marker) {
    //...
    return $lines;
}

Usage:

$lines = takeScriptsWithMarker($lines, $marker);
seanmonstar
A: 

like noted above in a previous answer, the issue is at CALL time, not definition time.. so you could define a function as:

function foo(&$var1,$var2,$var3=null){
    // procesing here
}

then call as:

$return = foo($invar1,$invar2);

your first invar is passed by reference, second one is not.

the error appears when you try to call like so:

$return = foo(&$invar1,$invar2);
Jason
A: 

You could pass an array with a reference in:

public function takeScriptsWithMarker(array(&$lines, $marker))

which should only take a small amount of refactoring at the other end.

jetboy