Extension from https://stackoverflow.com/a/55191/547210
I am creating a validating function to check several attributes of string variables, which may or may not have been set. (One of the attributes which is checked)
What I am trying to do with the function is receive arguments an unknown number of arguments in the form (See below), and suppress errors that may be caused by passing an unset variable.
I'm receiving the variables like validate([ mixed $... ] )
by using func_get_args()
The previous post mentioned that it was possible by passing by reference, now is this possible when the variables are passed implicitly like this?
1 Answers
If you pass a variable that is not set in the calling scope, the array returned by func_get_args()
will contain a NULL
value at the position where the variable was passed, and an error will be triggered. This error is not triggered in the function code itself, but in the function call. There is, therefore, nothing that can be done to suppress this error from within the code of the function.
Consider this:
function accepts_some_args () {
$args = func_get_args();
var_dump($args);
}
$myVar = 'value';
accepts_some_args($notSet, $myVar);
/*
Ouput:
Notice: Undefined variable: notSet in...
array(2) {
[0]=>
NULL
[1]=>
string(5) "value"
}
*/
As you can see, the variable name notSet
appears in the error, telling us that the error was triggered in the caller's scope, not that of the callee.
If we want to counter the error, we could do this:
accepts_some_args(@$notSet, $myVar);
...and prefix the variable names with the evil @
operator, but a better solution would be to structure our code differently, so we can do the checks ourselves:
function accepts_some_args ($args) {
var_dump($args);
}
$myVar = 'value';
$toPassToFunction = array();
$toPassToFunction[] = (isset($notSet)) ? $notSet : NULL;
$toPassToFunction[] = (isset($myVar)) ? $myVar : NULL;
accepts_some_args($toPassToFunction);
/*
Ouput:
array(2) {
[0]=>
NULL
[1]=>
string(5) "value"
}
*/

- 87,921
- 11
- 154
- 174
-
It seems to me like the "evil" @ symbol is much cleaner code than your "better solution", and therefore much less likely to introduce bugs. – Abhi Beckert Jan 10 '12 at 22:08
-
Shorter does not mean cleaner. By explicitly suppressing errors for one particular piece of code, you are potentially hiding errors that are preventing your code from working somewhere else. There are some rare cases where the use of `@` is legitimate (notably `fopen()`), but they are few and far between. Certainly using it to suppress errors about trying to use undefined variables is *not* a correct usage. Much like the `goto` debate - there are situations in which their use is acceptable and even good, but most people don't understand how to determine this, so the best approach is "don't". – DaveRandom Jan 10 '12 at 22:16
-
I thought that there wouldn't be a easy answer to this, its just that I have to carry out the same set of validation rules to many variables from `$_POST` and rather than checking isset first and then looping for each rule, it seemed a sensible way of cutting down on the amount code doing virtually the same thing. Out of interest what sort of errors could using the `@`s cause when the function is testing each variable with isset? – Olirav Jan 10 '12 at 22:44
-
@Olirav Why don't you just pass the whole `$_POST` array to the function, rather than specific keys? – DaveRandom Jan 10 '12 at 22:52
-
@DaveRandom I agree, it's a feature I only use once a year or so (in 40 hours/week of PHP programming). But I think this is a case where I would use it, along with a big honking comment explaining why. – Abhi Beckert Jan 11 '12 at 00:54