What's the best way of writing:
if(!$this->uri->segment('4') && $this->uri->segment('4') != 0)
This is far too long winded. Just need to check if a string is set, even if it's 0.
isset()
EDIT: nope this is not a var its a method..
Just need to check if a string is set, even if it's 0.
if($this->uri->segment('4') != '')
but i dont think this is what you are trying to do.
it depends on what this method returns and what you try to accomplish.
This is far too long winded. Just need to check if a string is set, even if it's 0.
How about checking for the length of the string?
if (strlen($this->uri->segment('4')) > 0)
EDIT For explicitness, I've added > 0, so it may be a little more descriptive what it is exactly you expect. This isn't necessary, however.
The first clause isn't "correct" anyway, as you've discovered by having to write the second one. You also have to consider FALSE and the empty string (""). Code like if ($var) is lazy and, usually, wrong.
The correct approach for testing a variable is the PHP function isset. However, assuming $this->uri->segment('4') is a function call, the result will always be "set". It can never not be set. So it seems unlikely to be that you can do much here.
What criteria are you really looking for?
Perhaps your function segment returns null? So write if (!is_null($this->uri->segment('4'))).
Or perhaps you're looking for the empty string? So write if ($this->uri->segment('4') != "").
1
if ( strlen($this->uri->segment('4')) )
{}
2
if ( strlen($this->uri->segment('4')) !== "" )
{}
Related
I want to check if a numeric variable has a value (including '0') and is not empty. Empty meaning EMPTY (''), not '0'.
Is this really the best I can do with PHP?
if (isset($variable) && $variable !== '') { ... }
I'd like to do this with one check without writing a function for it...
What you are trying to check is string length, not "empty". This can easily be done using strlen().
if (isset($variable) && strlen($variable) > 0) {
// Do something
}
If you want to exclude whitespace as invalid, you can add a trim() in there as well (generally recommended).
if (isset($variable) && strlen(trim($variable)) > 0 } {
// ...
}
The best thing you could do, is making your own custom function. The point is to pass the variables by reference to not trigger a warning, when you pass an undefined variable. As posted as comment, I'd use something along the line isset($variable) AND !empty($variable) AND !is_numeric($variable) AND $variable !== false to cover all cases.
Your custom function could look like this (improved version):
function is_blank(&$variable) {
return (bool) !(isset($variable) AND (!empty($variable) OR is_numeric($variable) OR $variable === false));
}
https://3v4l.org/ZcCDu
Yes, your way is the best (most efficient) way to:
insure the variable has been set (so you don't get an warning checking a variable that's not been set)
it's not the empty string ''
But, could be '0', 0,false, null, or [] which all count as empty in php, but you wish to consider as non-empty as indicated by your OP
your !== will ensure only exactly the string '' is compared (no casting/conversion)
The use of strlen works as well, but if you look at the opcode generated you'll see direct comparison is more 3 times computationally more efficient (assuming all operations are equally weighted, even more efficient if operations like DO_FCALL take significantly more cycles to execute than a basic IS_NOT_IDENTICAL check)
The !== ''version bytecode:
IS_NOT_IDENTICAL ~1 !0, ''
The strlen() > 0 version bytecode:
SEND_VAR !0
DO_FCALL 1 $1 'strlen'
IS_SMALLER ~2 $1, 0
(The answer has been edited. Consult the additionals further down under "ternary operations").
Why go through the trouble of using all that?
Just use an "not empty" if(!empty($var)){...}
However, if you're using this with a GET array, then yes; it would be best to use an isset() and empty() on a conditional statement.
I want to check if a variable has a value (including '0') and is not empty
That to me interprets as:
Check if a value has a value and is not empty (as you wrote) and stands to contain a 0 (zero).
Therefore:
if(!empty($var) && $var='0'){...}
I'd like to do this with one check without writing a function for it...
Use a ternary operator then.
However "without a function"... right well you can't. You still need "some type of function".
About that "ternary operator" I mentioned above. You can reference what are called "nested ternary operations" in both these Q&A's on Stack:
How to concatenate multiple ternary operator in PHP?
nested php ternary trouble: ternary output != if - else
That way you won't need a custom function.
Sidenote: I am by far not taking away or trying to take away from (Charlotte's) accepted answer (which should remain as accepted). This is just an additional method of achieving your (ultimate) goal.
This probably has been asked, but I couldn't find the exact answer I am seeking.
In javascript, I can simply do
if (a.b) {//do something}
But in PHP, if I do
if($a->b) {}
Basically it'll work, but I will get a notice if a has no b, so I switch to
if(isset($a->b)){}
That doesn't work because when a->b is an empty string, it will return true. So I ended up doing
if(isset($a->b) && $a->b !== ''){}
This seems redundant and not very bug-proof.
What is the best practice to do this?
empty checks if a variable is set, and contains data. If it's empty or not set, it will return true.
if(!empty($a->b)) {}
I am maintaining some old PHP code and I find many places in the code a test for a variable being non-empty of the following form:
if (!(isset($field_name) && strlen($field_name) > 0))
To my way of thinking, the following much simpler form would do exactly the same thing:
if ($field_name)
Am I missing some subltety whereby the more complex form is more precise? I have tended to use the simpler form any place where I need to add new code.
You can use empty() to replace your first line:
if (!empty($field_name))
The problem with your second example is that it will generate a warning if the variable is not set. Both empty() and isset() will not generate a warning for non-existing variables.
Note that you always have to account for possible values so if your value can be 0 or '0', this will not work as after $var = 0;, empty($var) will evaluate to true.
if ($field) will fail if $field is null, 0, 0.00, false or anything that can be casted false
if(!isset($field))
will fail if $field has not been declared at all
They do not do the same thing. The first code sample:
Checks if $field_name exists (I figure the ! is unintentional as it doesn't make sense the way it is written)
Checks if $field_name has a string length greater than zero
The second code sample:
Checks if the variable has a Boolean true value
Will throw an error if $field_name is not set.
The first snippet is clear and precise in its intent and performs a specific task.
The second snippet is very basic and only verifies the variable has a Boolean true value (and there are better ways to do that). If $field_name contains a string "0" this snippet will cause a hard to spot bug as it will fail as "0" evaluates to false. The first snippet would catch this.
You are right that the code you found is odd. It should probably be either:
if(!(isset($field_name)) { ... do something }
or
if(isset($field_name) && strlen($field_name) > 0 ) { ... do something }
...As you can appreciate, there is no need to test the length of a variable that is not defined.
However, if($field_name) is not the same as if(!(isset($field_name)), and the difference is not subtle. Indeed, the former will earn you a Undefined variable: fieldname if by some stroke of bad luck $field_name is not defined.
What's the difference?
if($field_name) tests if the existing variable $field_name evaluates to TRUE. For instance, it's value might be "my dog", and that evaluates to TRUE
if(!(isset($field_name)) tests if the variable $field_name exists at all.
i used this way to testing an array $arr if empty
if(!empty($arr)){ //do something }
recently, i saw someone use an another like:
if($arr){ //do something }
just want to know is't the second way a simply way to testing an array or is there some potential risk here ?
An empty array like array() is regarded as equal to false. So a simple if ($arr) works perfectly fine.
empty does the same kind of comparison, but does not trigger a NOTICE about missing variables, should the variable $arr not exist at all. You should not use empty if you are sure the variable exists, since it suppresses valuable error reporting. Only use empty if you really don't know whether a variable exists or not and have no control over it.
For more information about empty see The Definitive Guide To PHP's isset And empty.
The second casts the array to a boolean. Empty arrays are cast to false, anything else to true. So if($arr) and if(!empty($arr)) are functionally identical.
Both methods are functionally equivalent. The documentation for empty() mentions the following things are considered to be empty
"", 0, 0.0, "0", NULL, FALSE, array(), var $var;
Taking a look at casting to a bool, we can see that the list matches the list, which means both methods handle different types in the same way.
The second way is not ideal. If you use the second method and determine you're dealing with an array (and you aren't) and pass it to a foreach statement, you'll end up with an error. It is also more instructive for what you're checking to do more than test with if($arr).
My preference is:
if (is_array($arr) && count($arr) > 0) {
//work with array
}
Edit: I think my underlying point here is that the ability to test an array's existence is only part of the problem. If $arr turns out to be a string, a more robust check is needed.
I noticed this weird evaluation yesterday after searching for a few hours in my code for an error. i am passing scores into php, sometimes the score=0 which causes an issue.
send php ?blah=blah&score=0
if(!empty($_REQUEST['score']){
//do database update stuff
}else{
// show entire webpage
}
It works great unless the score=0 the if() will evaluate to false and return the entire webpage to my ajax handler and error. I have temporarily changed !empty to isset but this will cause problems in the future because isset evaluates to true even if the score key is in the url string without a value.
ex: (?blah=blah&score=&something=else)
my question is: what is the best way to recode this to work correctly now and in the future?
edit: there are a few working answers here, i appreciate everyones time. it was difficult to choose an answer
As the manual says, a variable is considered empty() if it has an empty or zero value.
So it will treat your variable wrongly as empty even though 0 is a perfectly acceptable value in your case.
If you need score to be a number, you could use isset() in combination with a is_numeric() check instead:
if((isset($_REQUEST['score']) and (is_numeric($_REQUEST['score'])){
Check out the manual page to see the kinds of values is_numeric() accepts. If score is always an integer, you can also use is_int((int)$_REQUEST['score']) but that will convert invalid input values to 0.
Additionally, as #sightofnick says, it's better to use explicit $_GET or $_POST instead of $_REQUEST.
Re your update:
In that case I would
Do check whether the variable is "0" (string "zero")
If it is "0", make it 0 (integer "zero")
If it is not 0, convert it to an integer (int)$_REQUEST["score"])
If the conversion resulted in 0, it was invalid input - exit
You have a valid integer variable.
empty() will return false if a value is zero. Use isset() or array_key_exists() instead, if you want to check if a variable in an array is set:
if (array_key_exists('score', $_REQUEST)) {...}
Try doing
if (isset($_REQUEST['score']) && ($_REQUEST['score'] !== '')) {
...
}
The isset will handle the presence/absence of the query parameter, and the strict string (!==) comparison will handle the case where the 'score' query is present but has no value. PHP treats all data coming from _GET/_POST/_REQUEST as strings, so this test is 100% reliable.
if(isset($_REQUEST['score']) && $_REQUEST['score'] != ''){
//do database update stuff
}else{
// show entire webpage
}
You may be able to solve that with
if (isset($_REQUEST['score']) && is_numeric($_REQUEST['score'])) {}
That of course if scrore can only contain numeric value