Pass by reference in function for isset() & empty() - php

Basically I wanted to avoid doing something like this:
if((isset($var_1) && !empty($var_1)) || (isset($var_2) && !empty($var_2)) ...) { ....
So I created a function to try and solve it:
function set($item) {
return (isset($item) && !empty($item));
}
When passing in a variable that isn't set, take for example this:
$args = ['derp'];
if(set($args[0]) || $args[1]) {....
I get a thrown Notice stating that "Offset 1 isn't set, but when I change the function to note $item by-reference, it drops the PHP Notice:
function set(&$item) {
return (isset($item) && !empty($item));
}
Here is a demo
My question is this - how is this working? Is it because it's referencing the original $args array? Am I going insane?

When a function takes a by-reference argument, warnings about it being undefined are disabled at the time of the call. This is because the function might be used to assign the variable, so it's not an error to pass an undefined variable, or nonexistent index. For instance, suppose you had a function like:
function setTo3 (&$arg) {
$arg = 3;
}
setTo3($array[1]);
There's no reason to warn about $array[1] not being defined, because setTo3() never uses the argument's value.

Related

Function to Avoid Variable Undefined

I am trying to write a function to avoid getting variable undefined error. Right now, i have a code like this:
function check($str){
if(isset($str)){
$s = $str;
} else {
$s = "";
}
}
check($_GET['var']);
The get var is not set. I am getting a variable undefined error on my screen. How do i alter my function to not throw this error and just return "" if it is not set? I don't want to have to code 100 if statements to avoid getting variable undefined. Thanks.
We already have in PHP a construct to check that. It is called isset(). With it you can check whether a variable exists. If you would like to create it with some default values if it doesn't exist yet, we also have syntax for it. It's null-coalescing operator.
$_GET['var'] = $_GET['var'] ?? '';
// or since PHP 7.4
$_GET['var'] ??= '';
Although I'm not sure if it is the right way of doing it, for the sake of providing an answer you can pass the variable by reference, this allows you to get away with passing undefined variables and check if it is set inside the function..
function check(&$str){
if(!isset($str)){
$str = "not set";
}
}
check($_GET['var']);
echo $_GET['var'];

How to dynamically set the argument to $_GET or $_POST?

I'm writing a function in php to check, if all arguments are set. This is for preventing the program to crash when a argument isn't set.
Unfortunately I get this error:
Notice: Undefined variable: _POST
The code running is the following:
# check for the right arguments
function checkArguments($type, $arg_array) {
# $type is either 'GET' or 'POST'
# $arg_array is an array with all the arguments names
foreach($arg_array as $arg) {
print(${"_" . $type}["name"]);
$type = "_" . $type;
if(!isset($$type[$arg])) {
$missing[] = $arg;
}
}
}
HI I will assume you wanted a variable variable, I try to avoid them as they are very hard to read in code. It also breaks ( or doesn't work in ) most IDE editors.
One thing I just saw that is relevant.
http://php.net/manual/en/language.variables.variable.php
Please note that variable variables cannot be used with PHP's Superglobal arrays within functions or class methods. The variable $this is also a special variable that cannot be referenced dynamically.
The $_POST would be counted among the "Superglobal" as is $_GET
You could assign them to a temporary variable and use that.
$arr = $_GET;
if ($type == "POST") $arr = $_POST;

Checking if an array key exists

I have a multidimensional array produced by json_decode(). The json is dynamically generated, that means some keys will be present randomly.
I would like to avoid Undefined index: notice, so i encapsulated the calls to the array in a function like this:
function exists($value) {
if (isset($value)) {
return $value;
}
}
I then call data:
$something = exists($json_array['foo']['bar']['baz']);
But i still get the Undefined index: baz notice. Any suggestions?
It seems you are new to PHP, so I'll give a bit lengthier answer than normal.
$something = exists($json_array['foo']['bar']['baz']);
This is equivalent to what you wrote:
$baz = $json_array['foo']['bar']['baz'];
$something = exists($baz);
As you may have noticed, this means that $json_array['foo']['bar']['baz'] is evaluated before it's passed to exists(). This is where the undefined index is coming from.
The correct idiom would be more like this:
$something = NULL;
if (isset($json_array['foo']['bar']['baz'])) {
$something = $json_array['foo']['bar']['baz'];
}
The following is also identical to the above lines:
$something = isset($json_array['foo']['bar']['baz'])
? $json_array['foo']['bar']['baz']
: NULL;
You would have to chain the exists calls one by one, because you are trying to dereference the array before you send it to the exists function.
See this question for more info: Check if a "run-time" multidimensional array key exists
$json_array['foo']['bar']['baz'] fails when you pass it as an argument, before it's passed to isset(). That is your problem.

I am looking for a php function that will prevent this: Undefined index: message in

if(defined($_POST["message"]) && defined($_POST["name"]))
{
In that if block an exception is thrown constantly. I am looking for a function that will prevent this by testing if it the post variable exists..if it doesnt exists return false instead of throwing an exception
if (isset($_POST["message"]) && isset($_POST["name"])) {
// ....
}
or if you want to check them to be not only set but also non-empty:
if (!empty($_POST["message"]) && !empty($_POST["name"])) {
// ....
}
Use isset() for determining if a variable is set. Use defined() to check if a constant is defined with the define() function.
See the Manual:
defined function
isset function
Use isset instead of defined.
if(isset($_POST["message"]) && isset($_POST["name"])) {
[...]
defined takes a string as an argument, and is for checking if a constant exists.

Using reference to nonexistent value sets variable to NULL?

When passing a non-existent value by reference, PHP creates the value and sets it to NULL. I noticed it when memory increases were occurring while checking empty values in some functions. Take the following function:
function v(&$v,$d=NULL){return isset($v)?$v:$d;}
$bar = v($foo, $default);
This would be shorthand for:
if(isset($foo))
{
$bar = $foo;
}
else
{
$bar = $default;
}
However, when passing non-existent variables PHP creates them. In the case of variables - they are removed as soon as the method/function ends - but for checking super global arrays like $_GET or $_POST the array element is never removed causing extra memory usage.
$request_with = v($_SERVER['HTTP_X_REQUESTED_WITH']);
Can anyone explain why this happens and if it is a PHP todo fix or a feature for some other crazy use of values?
XeonCross' function v is a shorthand for the often used:
$val= isset($arr['elm']) ? $arr['elm'] : 'default'
to avoid the dreaded 'Undefined index: elm' notice. A nice helper function would be:
function ifset(&$v1, $v2 = null) {
return isset($v1) ? $v1 : $v2;
}
as Xeoncross suggested, so you could write the much nicer
$val = ifset($arr['elm'],'default')
however, this has a lot of interesting (?) quirks in our beloved "language" that we call PHP:
inside the function ifset, $v1 seems UNSET, so it correctly returns the value $v2 and you might conclude that ifset works ok. But afterwards $arr['elm'] is silently set to NULL. So consider the following:
function wtf(&$v) {
if (isset($v))
echo "It is set";
else
echo "It is NOT set";
}
$p=[];
wtf($p['notexist']); => It is NOT set
$p; => [ 'notexist' => NULL ]
But this is another delusion, as the isset() function returns false for NULL values as well:
$x=NULL;
isset($x) => false... huh??
Did we expect this? well.. it is in the documentation, so this is by design as well. Welcome to the wonderful world of php.
The reason you have the memory leak, is because you're telling it to.
When you ask for a reference parameter, PHP will provide you with one. When you are calling a function with an unset variable, PHP will set the variable and then pass the reference to that new variable. When you call it with a superglobal, it creates the missing index. That's because you told it to.
However, I must ask why specifically do you need variable references? 99.9% of the time you don't really need them. I suspect that it'll work just fine to do:
function v($v, $d = null) { return isset($v) ? $v : $d; }
Or, if you really must use references (which you can't get around your original problem with), you should also return a reference:
function &v(&$v, $d = null) {
if (isset($v)) {
return $v;
}
return $d;
}
Otherwise it's pointless to take a reference and not return one...

Categories