I'm writing a functional that calls two nullable boolean APIs. If either API returns true, my function should return true. If both return false, my function should return false. Otherwise, my function should return null. In other words:
true, true -> true
true, false -> true
true, null -> true
false, false -> false
false, null -> null
null, null -> null
Is there a simple/elegant way to write this? Obviously an if-else chain like this would work, but I think it's fairly messy, especially since you have to account for that null is a falsy value.
if ($cond1 || $cond2) {
return true;
} else ($cond1 === false && $cond2 === false) {
return false;
} else {
return null;
}
Stick to what you suggested. One point of improvement is that you don't need if - else branching since you're returning. You just need two ifs:
function evaluate(?bool $cond1, ?bool $cond2): ?bool
{
if ($cond1 || $cond2) {
return true;
}
if ($cond1 === false && $cond2 === false) {
return false;
}
return null;
}
What about
return ($cond1 ? $cond1 : $cond2);
what about :
if($cond1 === true || $cond2 === true){
return true;
}else{ //check first and sec cond for falsing
if($cond1 === false && $cond2 === false){
return false;
}else{ //else null it
return null;
}
}
You can remove else if block like so:
if ($cond1 || $cond2) {
return true;
}
return !isset($cond1, $cond2) ? null : false;
You can simplify it down to:
return ($cond1 || $cond2) ? true : (!isset($cond1, $cond2) ? null : false)
But this gets hard to read and make sense of off.
Given your stipulations (and assuming each argument is one of: null, true or false) you could shave a smidgeon:
function foo($a, $b) {
if($a || $b) return true;
if([$a, $b] === [false, false]) return false;
}
Below seems to be working, I have tried to logic using Javascript as illustrated below
function testMyConditions($c1, $c2) {
return ($c1 === true || $2 === true) ? true: ($c1 === null || $c2 === null ? null: false)
}
function testMyConditions($cond1, $cond2) {
return ($cond1 === true || $cond2 === true) ? true: ($cond1 === null || $cond2 === null ? null: false)
}
function runTests($cond1, $cond2, $expected) {
console.log($cond1, $cond2, $expected, $expected === testMyConditions($cond1, $cond2) ? '=> OK': '=> NOT OK')
}
runTests(true, true, true)
runTests(true, false, true)
runTests(true, null, true)
runTests(false, false, false)
runTests(false, null, null)
runTests(null, null, null)
I have a problem with a form check that use an if statement with multiple 'and' and 'or' operators. This check return me an anomalous occasionally false value.
public function insert_checkForm($form) {
$form = array_filter($form);
if (
!isset($form['report_id']) ||
!isset($form['date']) ||
!isset($form['technical_id']) ||
isset($form['travel_go_from']) != isset($form['travel_go_to']) ||
isset($form['work_go_from']) != isset($form['work_go_to']) ||
!isset($form['travel_go_from']) &&
!isset($form['travel_go_to']) &&
!isset($form['work_go_from']) &&
!isset($form['work_go_to'])
) {
return false;
} else {
return $form;
}
}
Last question, the above code changes compared to this (in spite of the priorities of and operators)?
[...]
!isset($form['report_id']) ||
!isset($form['date']) ||
!isset($form['technical_id']) ||
(isset($form['travel_go_from']) != isset($form['travel_go_to'])) ||
(isset($form['work_go_from']) != isset($form['work_go_to'])) ||
(!isset($form['travel_go_from']) && !isset($form['travel_go_to']) && !isset($form['work_go_from']) && !isset($form['work_go_to']))
[...]
Thanks =)
The most common problem with isset() is that it returns false when the item is NOT SET but also returns false if the item IS SET && IS NULL.
isset($arr['nonexisting']); //this returns: false
$arr['existing'] = null;
isset($arr['existing']); //this returns: false
I'm sorry for the vaguely described title. This is what I want:
if($a[$f] === false || $a[$g] === false || $a[$h] === false || $a[$i] === false || $a[$j] === false)
{
// do something
}
I want to do something with the condition that actually triggered the statement (if a[$f] = true and a[$g] = false, I want to do something with $g).
I know that in this case, the first statement that went true (i.e. $a[$g] == false) triggers. But is there any way to do something with $g? I've never seen this in my programming life before and can't seem to find anything about it.
Thanks in advance.
--- Edit ---
I forgot to mention: I'm using a function on all the array data. So, shortened, I get this:
if(valid($a[$f]) === false || valid($a[$g]) === false)
{
// do something
}
--- Edit 2 ---
This piece of OOP-based PHP, where I'm in a class, is my code.
if($this->validatedText($product[$iName]) == false ||
$this->validatedUrl($product[$iUrl]) == false ||
$this->validatedNumber($product[$iTax]) == false ||
$this->validatedValuta($product[$iPrice]) == false ||
$this->validatedText($product[$iArticleNumber]) == false ||
$this->validatedText($product[$iDescription]) == false ||
$this->validatedText($product[$iMetaDescription]) == false ||
$this->validatedText($product[$iTitle]) == false)
{
// do something with the first iVariable
}
Simplest solution will be
if(false!==($sIndex = array_search(false, $a, 1)))
{
//your $sIndex is first index with false value
}
if you want all keys, you may use array_filter(), like this:
$rgFalse = array_keys(array_filter($a, function($x)
{
//here valid is your function
return false===valid($x);
}));
I can’t get the desired result from a series of conditions in an IF.
if (($varteam == $_POST['rteam1']) && ($varteam == $_POST['rteam2']) && ($varteam == $_POST['rteam3']) && ($varteam == $_POST['rteam4']) && ($varteam == $_POST['rteam5']))
{true}
else
{false}
Starting from the variable $varteam I want to obtain true if all the compared values are identical, otherwise false.
The compared values may also be null.
With the code I’ve posted it works if all the values are equal or different but I get true instead of false if one or more values are different.
Why does it happen?
I am guessing that you may get false positives when you have 0 mixed with null or false. Just to be on the safe side, use === instead of == so type checking is in effect. That way, null !== false !== 0.
if (($varteam === $_POST['rteam1']) &&
($varteam === $_POST['rteam2']) &&
($varteam === $_POST['rteam3']) &&
($varteam === $_POST['rteam4']) &&
($varteam === $_POST['rteam5']))
{
// true
}
else
{
// false
}
Is there a better way besides isset() or empty() to test for an empty variable?
It depends upon the context.
isset() will ONLY return true when the value of the variable is not NULL (and thereby the variable is at least defined).
empty() will return true when the value of the variable is deemed to be an "empty" value, typically this means 0, "0", NULL, FALSE, array() (an empty array) and "" (an empty string), anything else is not empty.
Some examples
FALSE == isset($foo);
TRUE == empty($foo);
$foo = NULL;
FALSE == isset($foo);
TRUE == empty($foo);
$foo = 0;
TRUE == isset($foo);
TRUE == empty($foo);
$foo = 1;
TRUE == isset($foo);
FALSE == empty($foo);
Keep an eye out for some of the strange == results you get with PHP though; you may need to use === to get the result you expect, e.g.
if (0 == '') {
echo "weird, huh?\n";
}
if (0 === '') {
echo "weird, huh?\n";
} else {
echo "that makes more sense\n";
}
Because 0 is false, and an empty string is false, 0 == '' is the same as FALSE == FALSE, which is true. Using === forces PHP to check types as well.