Reputation: 4016
Can someone explain to me why this strange thing is happening? I have an empty $_POST array and i want to use a variable in that array that might be defined or not (in that case - use some default value). To do so, i have a function to avoid using all those isset() or empty() checks:
function val(&$varToCheck, $defaultValue = false)
{
if (isset($varToCheck))
return $varToCheck;
return $defaultValue;
}
Now if i say:
val($_POST['test']); print_r($_POST['test']);
The $_POST array now contains a NULL value key "test". I assume this is happening because the variable is passed by reference and somehow auto-creates an array index. How could i avoid this behaviour?
Upvotes: 0
Views: 68
Reputation: 37365
Yes. That will work so because you're using a reference in your function. That will create array index. Shorter way to illustrate:
$array = [];
$foo = &$array['foo'];
Array is now:
array(1) {
["foo"]=>
&NULL
}
So index was created. That's how references work (when creating that references you increase refcount by one).
And - no: it is impossible to implement isset()
with a custom user-land function. That is because references in PHP are not pointers. You can not maintain scope with references.
You may use wrapper for arrays like
function valArray(array &$array, $index, $defaultValue = false)
{
if(array_key_exists($index, $array) && !isset($array[$index]))
{
//note, having index & having it set isn't same
$array[$index] = $defaultValue;
}
}
So check if index exist first. Usage is like:
$array = ['foo'=>null];
valArray($array, 'foo', false);
valArray($array, 'bar', true);
//var_dump($array);
Then your array won't have additional indexes after such check. But - this also uses references, it's tricky way and it reduces readability. I strongly recommend to use direct isset()
checks instead.
Upvotes: 2
Reputation: 522042
That's how call-by-reference works. Take this example:
function foo($bar, &$error) { ... }
foo('bar', $error);
echo $error;
The point of this pattern is that the variable $error
will be created in the calling scope and will be populated with error codes, so you have access to them later. So yes, your array key will be created for you if it doesn't exist.
What you are trying to do is simply nonsensical.
function foo($bar) {
isset($bar) ...
}
The isset
check within this function is entirely nonsensical, since $bar
is declared right there in the function signature. The variable is absolutely guaranteed to exist. You cannot use this construct to test whether some variable in the calling scope was set or not, whether you pass by reference or not. The variable exists within the function and is entirely independent of anything in the calling scope. You're only passing values into the function, not the variables themselves.
You have to use isset
directly on the $_POST
array in the calling scope, you cannot defer that into a different scope.
The only alternative is to pass the array and key separately:
val($_POST, 'test')
function val(array $array, $key) {
isset($array[$key]) ...
}
Upvotes: 0