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'))
): ?>
Related
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) )
Edit 3:
As requested, I'm trying to simplify my question.
Here is a sample of some of my data from a xml file:
<entry>
<title>Entry 1</title>
<f:max_value_a>499 999</f:max_value_a>
<f:max_value_b>999 999</f:max_value_b>
<f:min_value_a>0</f:min_value_a>
<f:min_value_b>500 000</f:min_value_b>
<f:min_value_c>1 000 000</f:min_value_c>
<f:value_for_a>5,10</f:value_for_a>
<f:value_for_b>4,50</f:value_for_b>
<f:value_for_c>3,90</f:value_for_c>
</entry>
<entry>
<title>Entry 2</title>
<f:min_value_a>0</f:min_value_a>
<f:value_for_a>4,20</f:value_for_a>
</entry>
<entry>
<title>Entry 3</title>
<f:max_value_a>1 999 999</f:max_value_a>
<f:min_value_a>100 000</f:min_value_a>
<f:min_value_b>2 000 000</f:min_value_b>
<f:value_for_a>3,735</f:value_for_a>
<f:value_for_b>3,445</f:value_for_b>
</entry>
f:value_for_d is the highest value, and f:value_for_c is lower than d, and so on.
I have a dynamic targetvalue (lets just go with 2 000 000 in this example)
I want to get the value where max_value is greater than the targetvalue, but sometimes max_value is not defined and then set to "0". "0" in max_value should mean unlimited "roof". The min_value can not be greater than targetvalue, but sometimes min_value is not defined and then set to "0". "0" min_value should mean a unlimited "floor".
I have tried with this code
if ($value_for_d > 0 ){
if (($min_value_d <= $targetvalue) xor ($min_value_d == 0)){
if (($max_value_d >= $targetvalue) xor ($max_value_d == 0)){
$query_result = TRUE;
$value = $value_for_d;
}
}
}elseif ($value_for_c > 0 ){
if (($min_value_c <= $targetvalue) xor ($min_value_c == 0)){
if (($max_value_c >= $targetvalue) xor ($max_value_c == 0)){
$query_result = TRUE;
$value = $value_for_c;
}
}
}elseif ($value_for_b > 0 ){
if (($min_value_b <= $targetvalue) xor ($min_value_b == 0)){
if (($max_value_b >= $targetvalue) xor ($max_value_b == 0)){
$query_result = TRUE;
$value = $value_for_b;
}
}
}elseif ($value_for_a > 0 ){
if (($min_value_a <= $targetvalue) xor ($min_value_a == 0)){
if (($max_value_a >= $targetvalue) xor ($max_value_a == 0)){
$query_result = TRUE;
$value = $value_for_a;
}
}
}
If I run this code with a targetvalue of "2 000 000", I get this result:
Entry 1 - 3.9 (correct value is 3.9)
Entry 2 - 0 (correct value is 4.2)
Entry 3 - 3.445 (correct value is 3.445)
If I set the targetvalue to even lower, to 500 000, I get 0 on all my entries.
Edit 4:
If I do:
var_dump($min_value_d,$max_value_d,$min_value_c,$max_value_c,$min_value_b,$max_value_b,$min_value_a,$max_value_a);
I get this output: https://dpaste.de/DtjhO/
If the regions are always exclusive and always in the right order, I'd suggest you do something like this:
<?php
if($min_value_d <= $targetvalue) {
$value = $value_for_d;
} else if($min_value_c <= $targetvalue) {
$value = $value_for_c;
} else if($min_value_b <= $targetvalue) {
$value = $value_for_b;
} else if($min_value_b <= $targetvalue) {
$value = $value_for_b;
}
?>
However, if they are not always exclusive, you should be returning some form of array, as it may fulfil multiple criteria:
Assuming that $min_value_x is not set when it is not in the XML (As in, no minimum) and $max_value_x is not set when it is not in the XML (As in, no maximum)
<?php
$values = array();
//if (there is no minimum or its smaller than target) and (there is no maximum or its larger than target) and at least one of them is non-null
if((is_null($min_value_d) || preg_replace('/([^0-9.])/i', '',$min_value_d) <= $targetvalue) && (is_null($max_value_d) || preg_replace('/([^0-9.])/i', '',$max_value_d) >= $targetvalue) && !(is_null($min_value_d) && is_null($max_value_d))) $values[] = $value_for_d;
if((is_null($min_value_c) || preg_replace('/([^0-9.])/i', '',$min_value_c) <= $targetvalue) && (is_null($max_value_c) || preg_replace('/([^0-9.])/i', '',$max_value_c) >= $targetvalue) && !(is_null($min_value_c) && is_null($max_value_c))) $values[] = $value_for_c;
if((is_null($min_value_b) || preg_replace('/([^0-9.])/i', '',$min_value_b) <= $targetvalue) && (is_null($max_value_b) || preg_replace('/([^0-9.])/i', '',$max_value_b) >= $targetvalue) && !(is_null($min_value_b) && is_null($max_value_b))) $values[] = $value_for_b;
if((is_null($min_value_a) || preg_replace('/([^0-9.])/i', '',$min_value_a) <= $targetvalue) && (is_null($max_value_a) || preg_replace('/([^0-9.])/i', '',$max_value_a) >= $targetvalue) && !(is_null($min_value_a) && is_null($max_value_a))) $values[] = $value_for_a;
?>
As it turns out, your items are formatted with spaces, thus when converted to a float for interpretation it only looked at the first set of numbers. preg_replace('/([^0-9.])/i', '', $var) removes anything non-numerical. (This is quite computationally expensive, mind)
I've been scratching my head for a while trying to figure this out.
I have an array which look something like...
$param = array(
"conditionType" => $_GET['conditionType'] ? strtolower($_GET['conditionType']) : "all",
"minPrice" => $_GET['minPrice'] ? $_GET['minPrice'] : false,
"maxPrice" => $_GET['maxPrice'] ? $_GET['maxPrice'] : false,
);
I need to check to make sure that all books returned are >= the min price and <= the max price, but if these user chooses not to specify a min or max price than the if statement needs to ignore this check.
if(($param['conditionType'] == "all"
|| ($param['conditionType'] == "new" && strtolower($book['sub_condition']) == "new")
|| ($param['conditionType'] == "used" && strtolower($book['sub_condition']) != "new"))
&& ($param['minPrice'] && $book['price'] >= $param['minPrice'])
&& ($param['maxPrice'] && $book['price'] <= $param['maxPrice'])
&& $book['price'] != "null"
){
$books[] = array(
"link" => $book['link'],
"listing_condition" => $book['sub_condition'],
"listing_price" => $book['price']
);
}
What can I change in the if statement to make sure this happens?
You need to restructure the parts that read like
&& ($param['minPrice'] && $book['price'] >= $param['minPrice'])
to instead read like
&& (!$param['minPrice'] || $book['price'] >= $param['minPrice'])
This follows your stated logic: either a min price should not be set, or it must be less than or equal to the book price.
you just need to negate this $param['minPrice'] to !$param['minPrice']
Hi all i have a post value which i am checking to see if its been posted it has atleast 4 numbers (digits) this works perfect.
if (isset($_POST['year']) &&
!preg_match('/([0-9]{4})/i', stripslashes(trim($_POST['year']))) ) {
now i want to check that the value is greater or = to a vairable and not sure how to achive what i need
i tried the below with no luck
$yearOff = date("Y")-150;
echo $yearOff;
if (isset($_POST['year']) &&
!preg_match('/([0-9]{4})/i', stripslashes(trim($_POST['year'])))
&& $_POST['year'] > $yearOff ) {
$ageerrors[] = '<span class="error">
You forgot enter your birth YEAR</span>';
}
Rather than an && you need an || OR condition to switch between the three possible invalid states (empty, not 4+ digits, or <= $yearOff:
if (!isset($_POST['year'])
// Lose the stripslashes()...
|| !preg_match('/([0-9]{4})/i',trim($_POST['year']))
|| $_POST['year'] > $yearOff
) {
// Invalid...
}
Note: It isn't clear from your description whether you want the value to be >= $yearOff or you want it to be < $yearOff. In other words, the code above is testing for the invalid state. Use whichever operator is appropriate for the invalid state.
Note 2: To test for at least 4 consecutive digits in the regex, a better pattern is something like:
/\d{4,}/
// If it must be *only* digits and no other characters, anchor with ^$
/^\d{4,}$/
There's no need for the overhead of a () capture group.
$yearOff = date("Y")-150;
echo $yearOff;
$input = #$_POST['year'];
if (!$input || strlen($input) !== 4 || $input < $yearoff) {
### MEEEP, ERROR ###
}
Explanation:
Input is set (not null which would be false), then it must have a string-length of four and finally it's numerical value must be higher or equal $yearOff.
I assigned the value of the input to it's own variable as well, because you only need to take it once out of $_POST.
As all these conditions are negated, I used the or || operator. Naturally the same can be expressed non-negated and with and:
if ($input && strlen($input) === 4 && $input >= $yearoff) {
### THIS IS CALL OKAY ###
}
To better debug this, the next step is to assign the validity to a variable as well:
$inputValid = $input && strlen($input) === 4 && $input >= $yearoff;
if (false === $inputValid) [
### MEEP, ERROR ####
}
Hope this is helpful.
$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