EASY! But which conditional statement works - php

Simple but this has always bothered me. Which is the best way to condition statement?
$foo = '1';
if($foo === '1' || $foo === '2' || $foo === '3')
{
// foo matches
}
or
if($foo === '1' || '2' || '3')
{
// foo matches
}
Which step works and is better. is there a better solution?

The second version will always evaluate to true.
If you want to compact the comparison against multiple alternatives then use:
if (in_array($foo, array('1', '2', '3') )) {
If you want to closely match the exact comparison === then you would however need:
if (is_string($foo) && in_array($foo, array(...))) {

$foo = 1;
if(in_array($foo, array(1, 2, 3))){
//foo matches
}

This is an alternative:
if($foo>0 && $foo<4){
}

Second if statement won't work. PHP doesn't work like that. Any number other than 0 (including negatives) evaluates to true when alone in an if statement. This is why you can do something like if(count($array)) without specifying that count($array) must be greater than 0.
Would be the same as if you had said:
if($foo === 1)
{}
elseif(2) //This will always trigger if $foo !== 1.
{}
elseif(3) //This will never trigger because of the last one
{}
Each condition is it's own self contained condition. Instead of reading it as just "or" or "and" read it as "or if" and "and if". So if $foo is 1 or if 2 or if 3 instead of if $foo is 1 or 2 or 3
If it's just numeric, then amosrivera's solution is the best. If it's for other types of data, then webarto/mario have a good solution.

Related

PHP "or" syntax statement

Moving over to PHP from another language and still getting used to the syntax...
What's the proper way to write this statement? The manual on logical operators leaves something to be desired..
if($var !== '5283180' or '1234567')
Generally, comparison is by using == and the reverse is !=. But if you want to compare values along with its data type, then you can use === and the reverse is !==.
Please refer to the documentation for more information.
You can use the following:
if($var!='5283180' || $var!='1234567')
Try this
if($var != '5283180' || $var != '1234567')
PHP's or functions identically to the normal ||, but has a lower binding precedence. As such, these two statements:
$foo = ($bar != 'baz') or 'qux';
$foo = ($bar != 'baz') || 'qux';
might appear to be otherwise identical, but the order of execution is actually quite
different. For the or version, it's executed as:
($foo = ($bar != 'baz')) or 'qux';
- inequality test is performed
- result of the test is assigned to $foo
- result of the test is ORed with the string 'qux';
For the || version:
$foo = (($bar != 'baz') || 'qux');
- inquality test is performed
- result of test is ||'d with 'qux'
- result of the || is assigned to $foo.
To build on the others, as the OP mentioned they are new to PHP, there is a couple things to be considered.
First off, the PHP or that you're looking for is the double line (||) and each item must be a statement on each side of the ||.
if ( $var !== '5283180' || $var !== '1234567')
addition:
As mentioned in the PHP Manual
The or operator is the same as the || operator but takes a much lower precedence.
Such as the given example (from manual):
// The constant false is assigned to $f and then true is ignored
//Acts like: (($f = false) or true)
$f = false or true;
Now as mentioned, there is the general comparison (== or 'Equal') and the type comparison (=== or 'Identical'), with both having the reverse (not). In the given example, the test will check that $var is not identical to the values.
From PHP Manual:
$a !== $b | Not identical | TRUE if $a is not equal to $b, or they are not of the same type.
With this said, double check that this is what you're actually trying to accomplish. Most likely you're looking for !=.

simple if statements (not short hand)

So today, as everyday, I was programming. Going along my usual business, typing away, listening to Daft Punk and various other groovy tunes. Then out of the blue, I had to write something along the lines of:
$x = 'a'; // For instance
if ($x == 'a' || $x == 'b') {
// ...
}
Simple enough, not too shabby I say. But wait! I thought to myself "there must be an easier way to do that - I'm repeating myself". So I set about attempting to solve this with the following code:
if ($x == ('a' || 'b')) {
// ...
}
However, that doesn't work. At all. It's always true. If $x is equal to a, b, c or cake. So I sulked, cried a little bit and have decided to ask Stackoverflow if any of you guys know why.
Thanks!
|| is the logical or, it evaluates the left side as boolean ('a', which is in boolean context true) and if that's true returns true, if not, it does the same thing for the right hand side.
var_dump('a' || 'b');
bool(true)
Now, this value is compared against a character, which, based on the crazy rules of PHP (loose comparison chart), will also be true:
var_dump('a' == true);
bool(true)
You're asking PHP to evaluate if $x is equal to the value of ('a' OR 'b'), which will ALWAYS return true since both 'a' and 'b' have nonzero values.
You must use the comparison operator individually in this case, or use nickb's suggestion from the comments.
It didn't worked because
$a = 'a' || 'b'; // true, since 'a' and 'b' considered truthy
In this case, your string literals will be converted to booleans.
And if your $x in the if is not an empty string or other string considered falsy they will be equal.
However you can write your if like this:
if (in_array($x, array('a', 'b', 'cake'))
If you feel that it makes your intent more clear.
I would do:
$valid = array('a', 'b');
if (in_array($x, $valid)) {
...
}
Simple enough!
...but, in retrospect, maybe you didn't want another way to do it?
As you know || is a logical operator and always return true or false(in another word 1 or 0).
So, code ('a' || 'b') always return true(1). In this above case $x contains value so due to automatic type conversation $x also set to true(1) so its if(1 == 1) and return always true.
try with bellow code
$x = false;
if ($x == ('a' || 'b')) { echo 'true'; } else{ echo 'false';}
Always return false.
See how php converts strings to boolean
php > var_dump((bool) "a");
bool(true)
php > var_dump((bool) "b");
bool(true)
php > var_dump((bool) "cake");
bool(true)
So basically you asking php if($x == true)
see http://php.net/manual/en/types.comparisons.php

can this conditional logic work in PHP?

I came across some code today where a string is compared to two values at the same time. I've never seen this before - will this work? Can someone explain it to me?
$foo = 'date';
if ($foo == ('date' || 'datetime')) {
echo "Hello world";
}
That won't work. Write if ($foo == 'date' || $foo == 'datetime').
Not only won't || work for selecting from a set, but also you use used a single =, which is for assignment rather than comparison.
In this case, the constant strings are compared using the boolean or operator. To do that, they are both converted to boolean. Since they are non-empty strings, they evaluate to true. true or true returns true, which is assigned to $foo which is compared to $foo. That comparison will always be true if $foo is 'date' or 'datetime' or about any other non-empty string.
So, whatever the previous value of $foo was, or even if it wasn't assigned at all, the if-expression always evaluates to true, so you always get the echo, and $foo will always be true afterwards.
This'll not work. ('date' || 'datetime') always evaluates to true.
Use this instead:
$foo = 'date';
if ($foo == 'date' || $foo == 'datetime') {
echo "Hello world";
}
You could try the following:
$haystack = array("date","datetime");
$needle = "date";
if (in_array($needle,$haystack)) {
// do something
}
No. the || or OR operators only work with Booleans. you'll need this condition:
if ($foo == 'date' || $foo == 'datetime') { ... }
But what if you have 10 possible values? You'll need one for each? yes and no.
Another possibility is to insert all the possible values into an array and check whether your value is possible by comparing it to that array, using in_array():
$possible_values = array('date', 'datetime');
if (in_array($foo, $possible_values)) { ... }

OR in PHP IF Statement

I am having trouble with my IF statement, it is always TRUE although this is incorrect. I'm using an OR operator as there are two possible scenarios I want to capture in the IF statement.
The array string ad_status is "1" but using the below -3 is returned, I'm expecting the IF to be FALSE. If I remove the OR and second statement from the IF, the result of the IF is correct.
What have I done wrong? Thanks.
if(($getadstatus['ad_status'] != "1" || $getadstatus['ad_status'] != "4"))
{
return -3;
exit;
}
Additional:
What I want to do is exit the function (not seen in full here) if ad_status does not equal 1 or 4. If it equals any other value other than 1 or 4, the IF statement should return TRUE and exit.
ad_status could be any value from 0 to 4.
What you are saying is that any value that is not 1 OR is not 4 should return true.
For '1' you get the statement
if( 1 != 1 || 1 != 4)
which translates to
if( false || true )
which is ofcourse true.
What you need is:
if(!($value == 1 || $value==4))
which is the same as (de Morgan's law)
if($value != 1 && $value != 4)
You check:
ad_status != 1 -> FALSE
ad_status != 4 -> TRUE
if (FALSE OR TRUE) is always TRUE.
To be what you expected, replace OR with AND:
if(($getadstatus['ad_status'] != "1" && $getadstatus['ad_status'] != "4"))
{
return -3;
exit;
}
It will always be true as any value can't be both '1' and '4' at the same time.
You should use && operator because use !=. If you want to use || you could write like this:
if (!($getadstatus['ad_status'] == "1" || $getadstatus['ad_status'] == "4"))
You want to use &&
if(($getadstatus['ad_status'] != "1" && $getadstatus['ad_status'] != "4"))
{
return -3;
exit;
}
I personally prefer in_array instead of OR in IF statemements. Eg:
$array = array(1,4);
if (!in_array($getadstatus['ad_status'], $array)) {
// do whatever
}
There are no errors there.
If ad_status == 1 then your second condition will get you into the If
$getadstatus['ad_status'] != "4"
is true therefore you will get return -3;
If i got what you want you should use AND
if ( $a!= 1 AND $a!= 4 )
humm, ok I think I see. I'm attempting to be too clever. I want to use a single IF statement to check for two non related conditions. If ad_status does not equal 1 OR 4, return -3 and exit the function.
Okay, no problem, that can be expressed, just formulate like you write:
$status = $getadstatus['ad_status']; // assign a variable as it makes things easier to read.
if ( !( $status==1 || $status==4 ) )
{
return -3;
}
So the ! (not) should be on the whole OR comparison as you wrote in your sentence. That's probably in code what you had originally in mind. But as the order is important, the other part of your condition needs to be inside brackets to be calculated first, before using the not (!) operator.
Added:
The more sub-conditions are part of a condition or expression, the more complex it gets. But the more often you formulate complex conditions the better you will get with them. To train, you can always split conditions over multiple lines and assign labels (variables) to their part:
$status = $getadstatus['ad_status'];
$statusIs1or4 = $status==1 || $status==4;
$statusIsNot1or4 = !$statusIs1or4;
if ($statusIsNot1or4) return -3;
For production code this might be overuse, but as it's always the authors choice how to write something, you can do whatever the language allows.

Does PHP have short-circuit evaluation?

Given the following code:
if (is_valid($string) && up_to_length($string) && file_exists($file))
{
......
}
If is_valid($string) returns false, does the php interpreter still check later conditions, like up_to_length($string)?
If so, then why does it do extra work when it doesn't have to?
Yes, the PHP interpreter is "lazy", meaning it will do the minimum number of comparisons possible to evaluate conditions.
If you want to verify that, try this:
function saySomething()
{
echo 'hi!';
return true;
}
if (false && saySomething())
{
echo 'statement evaluated to true';
}
Yes, it does. Here's a little trick that relies on short-circuit evaluation. Sometimes you might have a small if statement that you'd prefer to write as a ternary, e.g.:
if ($confirmed) {
$answer = 'Yes';
} else {
$answer = 'No';
}
Can be re-written as:
$answer = $confirmed ? 'Yes' : 'No';
But then what if the yes block also required some function to be run?
if ($confirmed) {
do_something();
$answer = 'Yes';
} else {
$answer = 'No';
}
Well, rewriting as ternary is still possible, because of short-circuit evaluation:
$answer = $confirmed && (do_something() || true) ? 'Yes' : 'No';
In this case the expression (do_something() || true) does nothing to alter the overall outcome of the ternary, but ensures that the ternary condition stays true, ignoring the return value of do_something().
Bitwise operators are & and |.
They always evaluate both operands.
Logical operators are AND, OR, &&, and ||.
All four operators only evaluate the right side if they need to.
AND and OR have lower precedence than && and ||. See example below.
From the PHP manual:
// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;
// The constant false is assigned to $f before the "or" operation occurs
// Acts like: (($f = false) or true)
$f = false or true;
In this example, e will be true and f will be false.
Based on my research now, PHP doesn't seem to have the same && short circuit operator as JavaScript.
I ran this test:
$one = true;
$two = 'Cabbage';
$test = $one && $two;
echo $test;
and PHP 7.0.8 returned 1, not Cabbage.
No, it doesn't anymore check the other conditions if the first condition isn't satisfied.
I've create my own short-circuit evaluation logic, unfortunately it's nothing like javascripts quick syntax, but perhaps this is a solution you might find useful:
$short_circuit_isset = function($var, $default_value = NULL) {
return (isset($var)) ? : $default_value;
};
$return_title = $short_circuit_isset( $_GET['returntitle'], 'God');
// Should return type 'String' value 'God', if get param is not set
I can not recall where I got the following logic from, but if you do the following;
(isset($var)) ? : $default_value;
You can skip having to write the true condition variable again, after the question mark, e.g:
(isset($super_long_var_name)) ? $super_long_var_name : $default_value;
As very important observation, when using the Ternary Operator this way, you'll notice that if a comparison is made it will just pass the value of that comparison, since there isn't just a single variable. E.g:
$num = 1;
$num2 = 2;
var_dump( ($num < $num2) ? : 'oh snap' );
// outputs bool 'true'
My choice: do not trust Short Circuit evaluation in PHP...
function saySomething()
{
print ('hi!');
return true;
}
if (1 || saySomething())
{
print('statement evaluated to true');
}
The second part in the condition 1 || saySomething() is irrelevant, because this will always return true. Unfortunately saySomething() is evaluated & executed.
Maybe I'm misunderstood the exact logic of short-circuiting expressions, but this doesn't look like "it will do the minimum number of comparisons possible" to me.
Moreover, it's not only a performance concern, if you do assignments inside comparisons or if you do something that makes a difference, other than just comparing stuff, you could end with different results.
Anyway... be careful.
Side note: If you want to avoid the lazy check and run every part of the condition, in that case you need to use the logical AND like this:
if (condition1 & condition2) {
echo "both true";
}
else {
echo "one or both false";
}
This is useful when you need for example call two functions even if the first one returned false.

Categories