Complicated `if`case, correct? - php

I'm trying really hard to figure out how to solve this problem. Please be gentle, i'm still learning!
There are four workplaces named: B.Avf, R.Avf, Office and Production. Products is passing theese workplaces. Now i'm building a script that can alert if the same product is passing the same workplace twice. Now, this is the hard part: If the product has passed "B.Avf" it can't pass "R.Avf" whitout an alert, same if the product has passed "R.Avf" it can't pass "B.Avf" whitout and alert. But if the product has passed for ex. "R.Avf" it´s ok to pass "Office" whitout an alert.
This is what i got so far: (It's like example number 5 =)
Maby should i create nested ifstatements instead?
This code will turn true all times!
PHP
if($_SESSION['user']['usr_workplace'] == "R.Avf" ||
$_SESSION['user']['usr_workplace'] == "B.Avf" &&
strpos($history, "R.Avf") !== FALSE ||
strpos($history, "B.Avf") !== FALSE)

Your if condition should be :
//IF this session user workplace is "B.Avf" or "R.Avf"
//AND "B.Avf" or "R.Avf" excist in history, then alert!
if(($_SESSION['user']['usr_workplace'] == "R.Avf" || $_SESSION['user']['usr_workplace'] == "B.Avf") && (strpos($history, "R.Avf") !== FALSE || strpos($history, "B.Avf") !== FALSE))

Your if statement can be made a lot simpler by removing one condition and still getting the desired result like so:
if(
($_SESSION['user']['usr_workplace'] == "R.Avf" || $_SESSION['user']['usr_workplace'] == "B.Avf")
&&
strpos($history, $_SESSION['user']['usr_workplace']) !== false
)
Notice how you don't need two strpos checks, as the first part of the if statement will only allow the second part to run if it was true.
It would be better to extract this to a method or simplify it further, but for what you've asked this will do :).

This works, it has the right braces:
if($_SESSION['user']['usr_workplace'] == "R.Avf" || ($_SESSION['user']['usr_workplace'] == "B.Avf" && (strpos($history, "R.Avf") !== FALSE || strpos($history, "B.Avf") !== FALSE)))
It checks for r.Avf first, OR and then checks all the conditions within the braces

you should break this if into 2 methods.
one should be called:
isUserSessionRBAvf($_SESSION['user']['usr_workplace'])
the other should check the strpos pos:
isHistoryAvf($history, "R.Avf")
and you would end up with just:
if(isUserSessionRBAvf(...) && isHistoryAvf(...))
this way you have a more readable code and easier to debug.
P.S. consider a different method naming

what you need to do is simply check with session value to $history so you will avoid checking two strpos() where you are doing static string checking:
here you are checking with static string:
strpos($history, "R.Avf") !== FALSE ||
strpos($history, "B.Avf") !== FALSE)
make it dynamic like this:
if($_SESSION['user']['usr_workplace'] == "R.Avf" || $_SESSION['user']['usr_workplace'] == "B.Avf" && strpos($history, $_SESSION['user']['usr_workplace']) !== FALSE )

Related

PHP - if single value equals multiple options

So I understand this - and comparing/checking values. However, I was messing about and noticed the outcome for all my tests were the same - some of which I was taught (a) didn't work or (b) was incorrect.
Note, I'm running PHP7. Okay, to my point. I was able to achieve the same outcome checking if a single value equals one of multiple options...
These work...why? Def not the way I learned.
if ($status == 'in-progress' || 'in-review')
// and even
if ($status == ('in-progress' || 'in-review')) // kind of similar to ASP.NET Razor
I normally would repeat the check, like so: if($stat == 'a' || $stat == 'b') or even in_array() which is essentially the same thing.
Is the first examples, correct? If not, why is it working? Or is this something frowned upon and not practiced - or maybe even something new?
First off to make it clear == has a higher precedence than ||. This means your two if statements look like this:
if (($status == 'in-progress') || 'in-review')
if ($status == ('in-progress' || 'in-review'))
Now for your first if statement regardless what value $status has and what the outcome of ($status == 'in-progress') is, since you have an OR in it and after it 'in-review' your if statement will always be true, since a non empty string is a truthy value.
For your second statement, this part ('in-progress' || 'in-review') comes literally down to TRUE || TRUE, which evaluates to TRUE. Now $status just needs to hold a truthy value and the if statement will be true.
No, that code will never work. || has a lower precedence than ==, so you're comparing $status against the first value, then boolean || "or" the other value
if (($status == 'foo') || ('bar'))
You have to compare the values individually:
if (($status == 'foo') || ($status == 'bar'))
And this gets tedious for many values. A quick hack is to use an array:
if (in_array($status, array('foo', 'bar', 'baz', 'qux', 'etc...')))

If statement with && and multiple OR conditions in PHP

I'm having trouble trying to make the statement below work the way I want it to.
I am trying to display an error message for an order form if at least one text field is not filled out. Below is a snippet of my PHP code. The 'cookieGiftBox' is the name of a checkbox that users can select and if it is selected, they must enter an amount of cookies under their desired flavors in the text fields provided. How can I display an error message to display when the checkbox IS selected but NO text fields have been filled out?
<?php
if (isset($_POST['cookieGiftBox'])
&& (!isset($_POST['sugar'])
|| ($_POST['chocolateChip'])
|| ($_POST['chocolateChipPecan'])
|| ($_POST['whiteChocolateRaspberry'])
|| ($_POST['peanutChocolateChip'])
|| ($_POST['peanutButter'])
|| ($_POST['tripleChocolateChip'])
|| ($_POST['whiteChocolateChip'])
|| ($_POST['oatmealRaisin'])
|| ($_POST['cinnamonSpice'])
|| ($_POST['candyChocolateChip'])
|| ($_POST['butterscotchToffee'])
|| ($_POST['snickerdoodle']))) {
$error.="<br />Please enter an Amount for Cookie Flavors";
}
?>
&& takes precedence over ||, thus you would have to use parentheses to get the expected result:
if (isset($_POST['cookieGiftBox']) && (!isset($POST['sugar']) || ...)
Actually, to get check if nothing is selected, you would do something like this:
if checkbox is checked and not (sugar is checked or chocolatechip is checked) or the equivalent:
if checkbox is checked and sugar is not entered and chocolatechip is not entered....
If you want to know more, search for information about Boolean algebra.
Update: In your example and in the correct syntax the sentence I took as an example would like this (for the first sentence, note the not (!) and the parentheses around the fields, not the checkbox):
if (isset($_POST['cookieGiftBox']) &&
!(
isset($_POST['sugar']) ||
isset($_POST['chocolatechip'])
)
) { error ...}
Or the second sentence, which might be easier to understand (note the && instead of ||):
if (isset($_POST['cookieGiftBox']) &&
!isset($_POST['sugar']) &&
!isset($_POST['chocolatechip'])
) { error...}
Using ands makes sure it is only true (and thus showing the error) if none of the sugar, chocolatechips, etc. fields are set when the giftbox checkbox is checked.
So if the checkbox is checked, and no fields are set it looks like this:
(true && !false && !false) which is equivalent to (true && true && true) which is true, so it shows the error.
If the checkbox is checked and sugar is entered it would look like this:
(true && !true && !false), equ. to (true && false && true), equ. to false and thus no error is shown.
If both sugar and chocolatechip are entered also no error will be shown.
I have simillar issue:
I try use:
if (isset($this->context->controller->php_self) && ($this->context->controller->php_self != 'category') || ($this->context->controller->php_self != 'product') || ($this->context->controller->php_self != 'index')){ ... }
Thats didn't work, I change it to:
if (isset($this->context->controller->php_self) && ($this->context->controller->php_self != 'category') && ($this->context->controller->php_self != 'product') && ($this->context->controller->php_self != 'index')){ ... }
I dont know it is correct?
Edit. This is not correct, but for now i didnt know how to fix it.

Display HTML if two conditions are true or another two are true or third part of conditions are true

I have php if statement that should display certain HTML code if two conditions are true or another two are true or third part of conditions are true.
I have several arrays - $Options_arr, $MoreOptions_arr, $Special_arr .
To explain in the easiest possible way I want to do this:
if(!empty($Options_arr[0]) && $Options_arr[0]!="") or
(!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="") or
(!empty($Special_arr[0]) && $Special_arr[0]!="")
{?> some HTML here
All help will be appreciated thank you.
empty() already checks for empty string "" so it's shorter:
if(!empty($Options_arr[0]) || !empty($MoreOptions_arr[0]) || !empty($Special_arr[0])) {
//some HTML here
}
BragG, you can use elseif
Like:
if((!empty($Options_arr[0]) && $Options_arr[0]!="") ||
(!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="") ||
(!empty($Special_arr[0]) && $Special_arr[0]!=""))
{
// some html or any code
}
I hope that is what you were looking for..
Feel free to ask any question.
You are just missing some brackets. Also || is more frequently used than OR
if((!empty($Options_arr[0]) && $Options_arr[0]!="") || (!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="") || (!empty($Special_arr[0]) && $Special_arr[0]!="")){
echo '<p>hello</p>';
}
You're basically already there...
if (
(!empty($Options_arr[0]) && $Options_arr[0]!="")
|| (!empty($MoreOptions_arr[0]) && $MoreOptions_arr[0]!="")
|| (!empty($Special_arr[0]) && $Special_arr[0]!="")
){
...do something
Basically you write an if statement that resolves if any of the sub-statements are true by joining the sub-statements together with ORs

PHP operators if statement 'and' and 'or'

I have an if statement that I want to control with having one field needing input and they have to pick one of the other 2 choices.
if(test1 && test || test3){
//Something here
}
Should I do it like this:
if(test1 && (test2 || test3)){
//do stuff
}
How would I go about doing this. I can't wrap my head around the logic...
if ($requiredField && ($optional1 || $optional2)) {
/* Do something */
}
For the /* Do something */ bit of code to be executed, the if statement has to evaluate to TRUE.
This means, that $requiredField must be TRUE, and so must be ($optional1 || $optional2).
For $requiredField to be TRUE, it just needs to be filled in - and for the second part: ($optional1 || $optional2) either optional1 or optional2 would do it.
Edit:
After rereading the question, it seems that I might have misunderstood you. If the user must enter one specific piece of information, and must choose only one (not both) out of two options - then the following should be used.
if ($requiredField && ($optional1 ^ $optional2)) {
/* Do something */
}
This means that $optional1 or $optional2 must be filled out - but not both of them.
From the sound of it, you want the latter:
if ($test1 && ($test2 || $test3)){
//do stuff
}
Think of it as two conditions needing to be met. This gives you those two conditions. The second condition just happens to be another condition. The first option you posted, however, is quite the opposite as it can allow execution if just $test3 is true
test1 && (test2 || test3) is very easy to understand from the first place - Choose test1 && (test2 || test3) means one the last two. Very clear.
test1 && test || test3 - doesn't seem to be correct:
test1 = false
test2 = false
test3 = true
false && false || true = true
doesn't actually fit your criteria.
... they have to pick one of the other 2 choices
I'm just throwing a guess out here. If you really want to ensure that one, but only one of the two other options are selected, then you need xor:
if ($required AND ($and_either XOR $or_other)) {
You can have 'nested' if statements withing a single if statement, with additional parenthesis.
if(test1 && (test2 || test3)){
//do stuff
}
Your logic is right but your sintax isnt, you should compare the values of the variables as show, or simply ignore them as saying you are trying to compare them as they are TRUE.
$test1=true;
$test2=true;
$test3=false;
if($test1==true && ($test2==true || $test3==true){ echo "YES";}
This will output YES.

php conventions in conditions

I have system, that using keywords for some data
There are normal keywords and meta keywords - To:all, Tomember: and Togroup:
and I have following condition to check meta keywords:
if ((strpos($kwd, 'To:all') === 0) ||
(strpos($kwd, 'Tomember:') === 0) ||
(strpos($kwd, 'Togroup:') === 0))
{
/* ... */
}
I think this way of identifying meta keywords is incorrect.
One more incorrect way is like this:
if ((strpos($kwd, 'To:all') !== FALSE) ||
(strpos($kwd, 'Tomember:') !== FALSE) ||
(strpos($kwd, 'Togroup:') !== FALSE))
{
/* ... */
}
And in my opinion the correct way is:
if ((substr($kwd,0,6) == 'To:all') ||
(substr($kwd,0,9) == 'Tomember:') ||
(substr($kwd,0,8) == 'Togroup:'))
{
/* ... */
}
Any thoughts?
Of the solutions you propose, the second is wrong because it will return true even if the meta-keywords do not appear in the beginning of $kwd. The other two work correctly.
An even better way would be:
function str_starts_with($haystack, $needle) {
return substr($haystack, 0, strlen($needle)) == $needle;
}
if (str_starts_with($kwd, 'To:all') ||
str_starts_with($kwd, 'Tomember:') ||
str_starts_with($kwd, 'Togroup:'))
{
// ...
}
strpos($kwd, 'To:all') === 0
will check if the $kwd string begins with To:all -- it'll check if the position of To:all in $kwd is 0.
strpos($kwd, 'To:all') !== FALSE
will check if the $kwd string contains To:all -- no matter at which position.
substr($kwd,0,6) == 'To:all'
whill check if the first 6 characters of $kwd are To:all -- which is equivalent to the first solution.
If you want to test the begins with case, you'll use the first or third solution.
Personnaly, I'd go with the strpos-based : I find it easier to read/understand ; but it's mainly a matter of personnal preferences.
If you want to test the contains case, you'll need to use the second solution.

Categories