Alternative to isset(user_input) in php - php

I was wondering whether is another way to check if a variable coming from user input is set and not null, besides (the obvious choice) isset().
In some cases, we may not be using $_POST to get the value, but some similar custom function. isset() can not be used on the result of a function call, so an alternative way to perform the same check must be made. Now, isset() verifies two things:
Whether the value was set.
Whether the value is null. But there is some difference between assigning a variable the null value ( $variable = NULL; ) and getting a null value due to empty input fields. Or at least so I read.
So, is there a good way of checking both these requirements without using isset() ?

The equivalent of isset($var) for a function return value is func() === null.
isset basically does a !== null comparison, without throwing an error if the tested variable does not exist. This is a non-issue for function return values, since a) functions must exist (or PHP will exit with a fatal error) and b) a function always returns something, at least null. So all you really need to do is to check for null, no isset necessary.
I've written about this extensively here: The Definitive Guide To PHP's isset And empty.
Beyond this, it depends on what exactly you want to check:
test if a key was submitted via GET/POST: isset($_POST['key'])
test if there's a value and whether it's not == false: !empty($_POST['key'])
test if it's a non-empty string: isset($_POST['key']) && strlen($_POST['key'])
perhaps much more complex validations: filter_input

Here are some options...
PHP 7.4+ : null coalescing assignment operator
$variable ??= '';
PHP 7.0+ : null coalescing operator
$variable = $var ?? '';
PHP 5.3+ : ternary operator
isset($variable) ?: $var = '';

You can also use !empty() in place of isset()
the function !empty() works for both isset() and check whether the value of any string is not null, 0 or any empty string.
I usually prefer !empty() whenever I need to compare variable existence or in terms of its value.

The best way is isset but if you insist ... try empty() and strlen() Function to check wether it is empty or string lenghth is bigger than so many characters.
strlen() returns a number, length of the variable passed to it.
empty() checks if it has character in it or if it is null. with empty() you have to be becareful because some functions return 0 or false which is not considered empty.
if(!empty($var))....
OR
if(strlen($var)>2)...

I do it in most cases like this:
$v = my_func();
if (isset($v) and $v) {
...
}

Related

PHP Shorthand ifelse understanding

I am trying to make some sense out of the following shorthand
$state = $account->getCity() ? $account->getCity()->getStates() : null;
Is my understanding right?
if $account->getCity() exist assign the value of $account->getCity()->getStates() to the $state variable else assign is null
Reason I am asking this is because I m getting the error
Error: Call to a member function getCity() on a non-object
If the code $state = $account->getCity() ? $account->getCity()->getStates() : null; does not check to see if $account->getCity() is null then how do I make it so it checks it.
The output I am trying to achieve is
if $account->getCity() is not null assign the value of $account->getCity()->getStates() to the $state else just make it null
Hopefully I am not sounding too confusing :)
You're currently using what is known as "ternary operator" shorthand. However, you're using the $account->getCity() method to try and check if $account->getCity() exists, resulting in the problem.
A better practice would be to use isset($account->getCity()) or (!empty($account->getCity())) to evaluate if it exists. It is worth noting that isset() will check if it exists, where as empty() will check if it exists AND is filled with a value. As comments mention, you may also need to check that the object is actually an object, which can be done with is_object($object), such as using (is_object($account) && !empty($account->getCity()).
A common issue seen is that a variable or object may be assigned, but the contents are empty, similar to using $variable = '';. Checking using empty() may save you the heartache of coming across this problem down the road.
An additional side note is that while ternary operators are fantastic, they are best used when both a true and false condition are supplied. If you insist, try to at least use null in place of '' in the operation.

Comma Operator PHP

Both these statements are true:
$_POST['foo'] = $_POST['bar'] = 'some string';
//1. with '&&' operator
if(isset($_POST['foo']) && isset($_POST['bar'])) {
echo true;
}
//2. with a comma
if(isset($_POST['foo'], $_POST['bar'])) {
echo true;
}
What is the difference (if any) between them?
There IS a difference, in practice. The meaning should be the same, however the "comma operator" version implements a "complete boolean evaluation" in this case. That is, if the first variable is not set, php won't look at the second since they're in a && relationship and the result can't be true anymore. (This is called a "short circuit" eval) In the second case, php must calculate both arguments before calling isset(...) so both values will be checked.
It's just the principle, yes, but sometimes it's very important, for example if the operands are function calls.
(Just a short reply to the commenter saying "isset does not take function calls" - it's not about isset, it's about implementing expressions in general. Stop calculating things as soon as the result is obvious, and spare yourself as many partial results as you can. Function arguments will do the opposite: they all get calculated before they get passed to the subroutine.)
There's no difference according to the PHP documentation: isset() function. Indeed, isset can take an infinity of argument and returns true if every variable passed exists. It's similar to test if each isset() of each variable is true.
The theory should be check, but the function takes only variable in argument as said by the doc:
isset() only works with variables as passing anything else will result in a parse error. For checking if constants are set use the defined() function.
... So there's no problem about priority of the compute of arguments.
Finally, be aware that the comma here isn't an operator. The comma here is used to separated arguments of the isset function. The previous explanation doesn't work with empty() for example since the empty function only takes 1 argument.
TL;DR: isset($a, $b) == isset($a) && isset($b), but empty($a, $b) is a syntax error.
The isset() function can accept multiple arguments. If multiple arguments are supplied, then it only returns true if all of them are set.
http://www.php.net/manual/en/function.isset.php
There's no difference, except for the fact that you are calling isset() twice in 1., effectively evaluating both returning values with the && operator, in 2. you are just using isset() with two arguments instead of one, separated with a comma.

PHP if (variable)

In various PHP tutorials I see this syntax -
if ($_POST) {
do something
}
I want to know whether this is equivalent to either isset or !(empty) (either one) or has different properties.
It attempts to evaluate the expression and cast it to boolean.
See 'Converting to boolean' at http://php.net/manual/en/language.types.boolean.php to see which values will be equivalent to true and which to false.
It does NOT however check for array key existence (i.e. isset), so if you try if ($_GET['somekey']) but somekey does not exist, you will see PHP Notice: Undefined index: somekey and then false will be assumed.
The best practice would be to perform empty() or isset() checks manually first as fits.
Good question. You are adressing one of PHPs dark sides if you ask me.
The if statement
Like in any other language I can imagine if evaluates the parameter to either true or false.
Since PHP doesn't really know types you could put any expression as parameter which will then be casted to bool as a whole
Following values are considered to be "FALSE"
boolean FALSE
integer 0
float 0.0
empty string
string "0"
any array with zero elements
NULL e.g. unset variables or $var = null
SimpleXML objects when created from empty tags
EVERY other value or expression result is casted to bool TRUE
Now, knowing this, all we need to find out is, what an expression or function returns when executed
If no POST data is set, the following expression would be TRUE
$_POST == FALSE
The isset function
isset returns bool TRUE when the given variable is set and not null.
parameters can be variables, array elements, string offsets and data members of objects.
In PHP 5.4 they fixed the behaviour with string offsets
$var = FALSE;
isset( $var ) === TRUE;
$var === FALSE;
More here
http://de1.php.net/manual/en/function.isset.php
The empty function
Returns false when a variable is considered to be empty or does not exist.
Those values are considered empty:
Returns FALSE if var exists and has a non-empty, non-zero value. Otherwise returns TRUE.
The following values are considered to be empty:
"" (empty string)
0 (integer)
0.0 (float)
"0" (string)
NULL
FALSE
array() (empty array)
Also declared variables without value are empty
compare table
$var = FALSE;
isset($var) === TRUE;
empty($var) === TRUE;
$var === FALSE;
if ($_POST)
This will evaluate to true if there are any elements in the POST array.
if(isset($_POST))
This will always evaluate to true because the POST array is always set, but may or may not contain elements, therefore it is not equivalent to the first example.
if(!empty($_POST))
This however, is equivalent to the first example because empty() checks for contents in the array.
A good generic way of testing if the page was posted to is:
if($_SERVER['REQUEST_METHOD'] == 'POST')
$_POST:
this is used to find whether data is passed on using HTTP POST method and also extracting the variables sent through the same which are collected in an associative array
isset:
checks whether a variable is set(defined) or is NULL(undefined)
PHP.net is an invaluable source of information for figuring out the intricacies and quirks of the language.
With that said, those are not equivalent. The if statement converts the expression to a boolean value (see here for information on what is considered false).
isset is used to "determine if a variable is set and is not NULL."
empty determines whether a variable is empty, i.e., "it does not exist or if its value equals FALSE."
Best practice if you want to check the value of a variable but you aren't sure whether it is set is to do the the following:
if(isset($var) && $var) { ... }
ie check isset() AND then check the variable value itself.
The reason for this is that if you just check the variable itself, as per the example in your question, PHP will throw a warning if the variable is not set. A warning message is not a fatal error, and the message text can be suppressed, but it's generally best practice to write code in such a way that it doesn't throw any warnings.
Calling isset() will only tell you whether a variable is set; it won't tell you anything about the value of the variable, so you can't rely on it alone.
Hope that helps.

Is this an OK test to see if a variable is set

Yesterday, I posted an answer to a question that included several (unknown to me at the time) very bad code examples. Since then, I've been looking at my fundamental knowledge of PHP that allowed me to think that such code is possible. This brings me to a question that I can't seem to find an answer to:
If I want to check for whether or not a variable has anything set, is it a valid practice to not use isset() or another helper function? here's a "for instance":
if($not_set){
//do something
} else {
//do something else
}
Rather than...
if(isset($not_set)){
//do something
} else {
//do something else
}
From the name of the variable, you can see that this variable is not set. Therefore the conditional would be false and the else portion would run. Up until now I have been using this practice, but after the posts yesterday, I now have an inkling that this is wrong.
Here's why I thought that it would be an ok practice to leave out the isset() function above. From PHP manual:
The if construct is one of the most
important features of many languages,
PHP included. It allows for
conditional execution of code
fragments. PHP features an if
structure that is similar to that of
C:
if (expr) statement
As described in the section about
expressions, expression is evaluated
to its Boolean value. If expression
evaluates to TRUE, PHP will execute
statement, and if it evaluates to
FALSE - it'll ignore it. More
information about what values evaluate
to FALSE can be found in the
'Converting to boolean' section.
And from the 'Converting to boolean section':
When converting to boolean
, the following values are considered
FALSE:
...
* the special type NULL (including unset variables)
Why would the manual go out of its way to state that unset variables are included if this is a bad practice? If it's unset, it gets converted to NULL and therefore is evaluated properly by the conditional. Using isset() will find the same result, but will take extra cycles to do so.
Have I been wrong this whole time, and if so, why? (And just how bad it is, maybe?)
If the variable is not set you get a Notice. If you use isset() you don't get a notice. So from an error reporting point of view, using isset() is better :)
Example:
error_reporting(E_ALL);
if($a) {
echo 'foo';
}
gives
Notice: Undefined variable: a in /Users/kling/test on line 5
whereas
error_reporting(E_ALL);
if(isset($a)) {
echo 'foo';
}
does not output anything.
The bottom line: If code quality is important to you, use isset().
It's okay but not good practice to use if to check for a set variable. Two reasons off the top of my head:
Using isset makes the intent clear - that you're checking whether the variable is set, and not instead checking whether a condition is true.
if ($not_set) will evaluate to false when $not_set is actually set but is equal to boolean false.
You will run in to problems if your variable is set, but evaluates to FALSE, like the following:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the
string "0"
an array with zero elements
an object with zero member
variables (PHP 4 only)
the special type NULL (including
unset variables)
SimpleXML objects created from empty
tags
Taken from the PHP manual.
Basically, using isset() is showing that you are explicitly checking if a variable exists and is not NULL, while the structure of your if statement only checks if the variable is true. It is more clear and less error-prone.
It is a common practise, but is not good -- you should always use isset!
If your $not_set is set, and is a bool with the value false, your "test" will fail!
isset works as a guard preventing you from using variables that do not actually exist.
if (isset($foo)) and if ($foo) do not mean the same thing. isset just tells you if the variable actually exists and if it's okay to use it, it does not evaluate the value of the variable itself*.
Hence, you should usually use one of these two patterns:
If the variable is sure to exist and you just want to check its value:
if ($foo == 'bar')
If the variable may or may not exist, and you want to check its value:
if (isset($foo) && $foo == 'bar')
If you're just interested that a variable is set and evaluates to true, i.e. if ($foo), you can use empty:
if (isset($foo) && $foo)
// is the same as
if (!empty($foo))
* it does check for null, where null is as good as not being set at all

Detecting insufficient PHP variables: FALSE vs NULL vs unset() vs empty()?

What is the best way to define that a value does not exist in PHP, or is not sufficent for the applications needs.
$var = NULL, $var = array(), $var = FALSE?
And what is the best way to test?
isset($var), empty($var), if($var != NULL), if($var)?
Initializing variables as what they will be, e.g. NULL if a string, array() if they will be arrays, has some benefits in that they will function in the setting they are ment to without any unexpected results.
e.g. foreach($emptyArray) won't complain it just wont output anything, whereas foreach($false) will complain about the wrong variable type.
But it seams like an unnecessary hassle to have so many different ways of doing basically the same thing. eg. if(empty($var)) or if ($var == NULL)
Duplicate: Best way to test for a variable’s existence in PHP; isset() is clearly broken
Each function you named is for different purposes, and they should be used accordingly:
empty: tells if an existing variable is with a value that could be considered empty (0 for numbers, empty array for arrays, equal to NULL, etc.).
isset($var): tells if the script encountered a line before where the variable was the left side of an assignment (i.e. $var = 3;) or any other obscure methods such as extract, list or eval. This is the way to find if a variable has been set.
$var == NULL: This is tricky, since 0 == NULL. If you really want to tell if a variable is NULL, you should use triple =: $var === NULL.
if($var): same as $var == NULL.
As useful link is http://us2.php.net/manual/en/types.comparisons.php.
The way to tell if the variable is good for a piece of script you're coding will entirely depend on your code, so there's no single way of checking it.
One last piece of advice: if you expect a variable to be an array, don't wait for it to be set somewhere. Instead, initialize it beforehand, then let your code run and maybe it will get overwritten with a new array:
// Initialize the variable, so we always get an array in this variable without worrying about other code.
$var = array();
if(some_weird_condition){
$var = array(1, 2, 3);
}
// Will work every time.
foreach($var as $key => $value){
}
Another thing to remember is that since php is liberal in what it allows to evaluate to NULL or empty, it's necessary to use the identity operators (===, !== see http://php.net/operators.comparison. This is the reason why all of these comparison and equality functions exists, since you often have to differentiate between values with subtle differences.
If you are explicitly checking for NULL, always use $var === NULL
My vote goes for unset(), because non existing variables should generate an notice when used.
Testing gets a bit more complicated, because isset() wil be false if the variable is "not existings" or null. (Language designflaw if you'd ask me)
You could use array_key_exists() for valiables in $GLOBALS, $_POST etc.
For class properties there is property_exists().

Categories