PHP Operator failing - php

I am using this code to select and compare dates and information from 2 separate MySQLi tables. The code should produce the "discount_amount"IF the discount code entered is the same as the discount code in the database OR the discount code in the database is set to "open". Yet even with the dates set and the code set to "open" I am only getting the discount_amount if I type "open" in to the "$design_discount_code" manually.
if($discount_code == $design_discount_code or $discount_code == 'open' && $date >= $discount_start_date && $date <= $discount_end_date){
$design_price_total = $discount_amount;
$discount = 'yes';
} else {
$design_price_total = $original_price;
$discount = 'no';
}
I have also attempted to change the PHP operator to || and xor with no better results. Any ideas as to why it is only returning 'yes' when I type "open" and not automatically as it should?

You seem to assume that or has higher precedence than and. This is incorrect. You should use parentheses to indicate that the or check is one of the and conditions. Like this:
if(($discount_code == $design_discount_code or $discount_code == 'open') and $date >= $discount_start_date and $date <= $discount_end_date)
Also note that mixing the English and/or with the symbolic &&/|| is not a great idea.

Check the priority of the and and or, maybe you can use parentheses () to specify which should be evaluated first.
if( ( $discount_code == $design_discount_code || $discount_code == 'open') && ( $date >= $discount_start_date && $date <= $discount_end_date) )

Related

PHP - How to add up points from a specific value only

I want to add up points from the "vak" which is "wiskunde" if the box "vak" is filled with something else than the afformentioned "vak" "wiskunde" it doesnt need to be added up.
pastebin code ugwwDda8
<?php
if($_GET);
{
$jp = $_GET["janpunten"];
$pp = $_GET["pietpunten"];
$kp = $_GET["klaaspunten"];
$janvak = "";
$pietvak = "";
$klaasvak = "";
$totaal = "0";
if ( $janvak && $pietvak && $klaasvak = "Wiskunde" ) {
$totaal = $jp + $pp + $kp;
}
}
?>
So for example, the logic here would be if $janvak $pietvak $klaasvak are all wiskunde, they would add up all the points, but if only $janvak and $pietvak were wiskunde, it would only add up the points from those two.
This doesn't do what you probably think it does:
if ( $janvak && $pietvak && $klaasvak = "Wiskunde" )
This may make sense linguistically when spoken aloud in human languages, but computers don't have human intuition. Each part between the && operators is its own distinct boolean operation. So it's equivalent to this:
if ( ($janvak) && ($pietvak) && ($klaasvak = "Wiskunde") )
There's a pretty good chance that all three of these will always be true. (Or perhaps the first two will always be false? Since they're just empty strings. Either way, the code isn't doing what you want it to do.)
Additionally, you're using the assignment operator (=) instead of the comparison operator (==), so that will also always be true and will modify that variable when performing the if check.
It looks like what you wanted was this:
if ( $janvak == "Wiskunde" && $pietvak == "Wiskunde" && $klaasvak == "Wiskunde" )
When chaining together any combination of boolean logic operations, always make sure that each individual operation is a complete and distinct component of the overall logic.

Multi Conditional PHP IF statement only if variable has value

I have the following if statement, I want to return TRUE if example = sidebar, date start < now, and date end > now. It works as is but the problem is if one of the values doesn't exist, the statement is false.
How can I change the statement to only add conditions if each variable ($position,$date_start, $date_end) isset ? If one of the variables is not set, that portion the condition will be ignored.
For example, if there was no date_end, it would only evaluate for position and date_start
<?php
if ($position == "sidebar" &&
$date_start < strtotime('now') &&
$date_end > strtotime('now')):
?>
You want to check if each variable is not set OR if it equals the desired value
<?php if (
(!isset($position) || $position == "sidebar") &&
(!isset($date_start) || $date_start < strtotime('now')) &&
(!isset($date_end) || $date_end > strtotime('now'))
): ?>
If you want to allow unset, null, '' (empty string), and 0 values in addition to the specified string values, then you can check empty() instead of isset()
<?php if (
(!empty($position) || $position == "sidebar") &&
(!empty($date_start) || $date_start < strtotime('now')) &&
(!empty($date_end) || $date_end > strtotime('now'))
): ?>

how to write single line if statement with multiple conditions?

I'm currently working on a foreach loop with nested if statements but I'm pretty sure there's a better way of writing these chunks of if statements.
I found this post: PHP if shorthand and echo in one line - possible?
Though this post is for single conditions, I would like to write mine in the same way(single lined).
I'm not that experienced in PHP myself so I'm sort of stuck on doing it the old fashioned way:
if(($colorLevel['name'] === 'ATTR_VPMCV13') && ($colorLevel['level'] >= 80))
{
$prominentSideNumberArray[] = 10;
}
elseif(($colorLevel['name'] == 'ATTR_VPMCV13') && ($colorLevel['level'] >= 60) && ($colorLevel['level'] <= 70)){
$prominentSideNumberArray[] = 8;
}
If someone could properly explain what code to use where and why, that could really help me, and/or others, out. I've looked at the manual but I just can't figure out what to use where.
There is no such thing like an "if shorthand".
?: is an operator, if is a control structure. They are different language concepts that have different purposes and do different things. An expression that contains the ternary conditional operator (?:) can always be rewritten as two expressions and an if/else statement. The vice-versa is usually not possible.
The code you posted can be written to be much easier to read if you extract the common checking of $colorLevel['name'] into a separate if that includes the rest of the tests, extract $colorLevel['level'] into a new variable with shorter name and make the conditions that use $colorLevel['level'] use the same rule:
$level = $colorLevel['level'];
if ($colorLevel['name'] == 'ATTR_VPMCV13') {
// Don't mix '<=' with '>=', always use '<='...
if (60 <= $level && $level <= 70) {
$prominentSideNumberArray[] = 8;
// ... and put the intervals in ascending order
} elseif (80 <= $level) {
$prominentSideNumberArray[] = 10;
}
}
If there are multiple if statements that verify different values of $colorLevel['name'] then the intention is more clear if you use a switch statement:
$level = $colorLevel['level'];
switch ($colorLevel['name'])
{
case 'ATTR_VPMCV13':
if (60 <= $level && $level <= 70) {
$prominentSideNumberArray[] = 8;
} elseif (80 <= $level) {
$prominentSideNumberArray[] = 10;
}
break;
case '...':
// ...
break;
default:
// ...
break;
}
You can achieve this by using a ternary operator. Look at the following code:
$prominentSideNumberArray[] = ((($colorLevel['name'] === 'ATTR_VPMCV13') &&
($colorLevel['level'] >= 80) )? 10 : (($colorLevel['name'] == 'ATTR_VPMCV13') &&
($colorLevel['level'] >= 60) && ($colorLevel['level'] <= 70)?8:"")) ;
EDIT As per comments and you have to compare same value its better to define name
$color_name = "ATTR_VPMCV13";
if($colorLevel['name'] == $color_name )
$prominentSideNumberArray[] = (($colorLevel['level'] >= 80)? 10 : (
($colorLevel['level'] >= 60) && ($colorLevel['level'] <= 70)?8:"")) ;
DEMO with different approach
EDIT
Keep in mind that this solution is less readable than if-else statement.

Security of a simple numerical comparison

Ok I'm feeling like I'm going back not forward, can't even figure out by myself if a simple if statement is secure or not...
First of all let's say we get a variable from url GET method :
$my_number = $_GET['numb'];
Now we make this simple if statement:
if(($my_number >= 1) && ($my_number <= 12))
{
put $my_number in database without escaping it
}
So the question would be - Can user pass this if condition with something else besides 1-12, I mean using hex numbers, commenting, doing that kind of stuff?
To validate a number use intval()
$my_number = intval($_GET['numb']);
Nothing but a number will be allowed.
This will also insure the value will not create an error in the SQL.
I do not like >= or <=
if(($my_number >= 1) && ($my_number <= 12))
Change to:
if(($my_number > 0) && ($my_number < 13))
Your code is not fully secured. User can pass this if condition with something else besides 1-12.
You can test that with this simple code:
<?php
$my_number = $_GET['numb'];
if(is_numeric($my_number)){
if(($my_number >= 1) && ($my_number <= 12))
{
echo'User Can Pass';
}else{
echo'User Can Not Pass';
}
}else{
echo'User Can Not Pass';
}
?>
Now browse your site like http://example.com/?numb=8 or http://example.com/?numb=15 or http://example.com/?numb=7 Samurai
I think now you can find your answer. Thanks.

Getting wrong plural from calculation

$n=21;
$p=$n%10==1 && $n%100!=11 ? 0 : $n%10>=2 && $n%10<=4 && ($n%100<10 || $n%100>=20) ? 1 : 2;
why is $p = 2?
it is supposed to be $p = 0!
is it a bug or am I missing something?
I got this from trying to get the plural form for Russian on: http://www.gnu.org/s/hello/manual/gettext/Plural-forms.html
should be this one:
$p=($n%10==1 && $n%100!=11) ? 0 : (($n%10>=2 && $n%10<=4 && ($n%100<10 || $n%100>=20)) ? 1 : 2);
the error was in missing bracets
you can see here: http://php.net/manual/en/language.operators.comparison.php that "It is recommended that you avoid "stacking" ternary expressions. PHP's behaviour when using more than one ternary operator within a single statement is non-obvious". You can see that if you enclose the else part for the first if between ( and ) you will get another result:
$p=$n%10==1 && $n%100!=11 ? 0 : ($n%10>=2 && $n%10<=4 && ($n%100<10 || $n%100>=20) ? 1 : 2);
Maybe you should consider changing you statement to a "regular" if block, something like:
if ($n%10==1 && $n%100!=11)
{
$p =0 ;
}
elseif ($n%10>=2 && $n%10<=4 && ($n%100<10 || $n%100>=20))
{
$p = 1;
}
else
{
$p= 2;
}
this way being easier to read

Categories