PHP use result of as variable - php

Is it possible to use the result of an if with an OR statement as a variable for a function?
As example:
$a = true;
$b = false;
if ($a || $b) {
$this->functionCall($a)
}
Other example:
$a = false;
$b = true;
if ($a || $b) {
$this->functionCall($b)
}
Third and final exmaple:
$a = true;
$b = true;
if ($a || $b) {
$this->functionCall($a, $b)
}
So I need to detect what variable is true and pass it as a paramater. Is this even possible?
Any helps is appreciated!
Many thanks in advance

I'd do the logic bit inside a two-parameter function if I were you, as such :
function myFunc($a = false, $b = false) {
if ($a == true)
echo 'a';
if ($b == true)
echo 'b';
}
myFunc(); // echoes nothing
$a = true;
$b = false;
myFunc($a, $b); // echoes 'a'
$a = false;
$b = true;
myFunc($a, $b); // echoes 'b'
$a = true;
$b = true;
myFunc($a, $b); // echoes 'ab'

PHP 5.6+ version, filter out the falsely values (you can pass a callback to array_filter for different checks) and use those with the splat operator.
$params = array_filter([$a, $b]);
$this->callFunction(...$params);
No need for any IF checks and confusing in IF assignments.
Explore Variadic functions and Argument unpacking.

Related

OR Preference changing with a return

From what I see operator precedence makes sense in these two examples:
$a = false;
$b = true;
$c = $a || $b;
Here $c is true
$a = false;
$b = true;
$c = $a or $b;
Here $c is false
I understand the reasoning behind it. However the following:
$a = false;
$b = true;
return $a or $b;
Returns true, which puzzles me.
What is the reason for this?
or has lower precedence than =, so this:
$c = $a or $b;
Becomes this:
($c = $a) or $b;
But this doesn't make sense:
(return $a) or $b;
So you get this:
return ($a or $b);
Within an expression, operator precedence applies. =, || and or are all operators and $c = $a or $b is an expression. And according to operator precedence it evaluates as ($c = $a) or $b.
However, return is a statement. return is not an operator and does not group by operator precedence. It always evaluates as return <expression>, and therefore always as return ($a or $b).
The result of the expression $c = $a or $b is true BTW. $c is being assigned false in the course of the expression, but the expression overall returns the value true ($b). So even this would return true:
return $c = $a or $b;

2 PHP arrays for merge

How to delete element from array as it has partial in another?
Other words, I need to compare 2 array likely in_array php function, but partially.
Code:
$a = ['abc', 'cde', 'efg', 'hi'];
$b = ['bce', 'ifg', 'hig'];
// return $b without 'hig' because in $a has partially 'hi'
Thanks very much for any solution!
If you want to make any string in $b not have any string in $a as a substring. demo
<?
$a = ['abc', 'cde', 'efg', 'hi'];
$b = ['bce', 'ifg', 'hig'];
$b = array_filter($b, function($v) use($a){
foreach($a as $str){
if(strpos($v, $str) !== false)
return false;
}
return true;
});
print_r($b);
You can use array_filter() to filter the array with anonymous function. Then a combination of array_diff() and str_split() to compare each letters of each elements. This works even if the letters on the element of $a array is shuffled
$a = ['abc', 'cde', 'efg', 'hi'];
$b = ['bce', 'ifg', 'hig'];
$b = array_filter($b, function($bElem) use($a) {
foreach ($a as $aElem) {
$diff = array_diff(
str_split($aElem),
str_split($bElem)
);
if (empty($diff)) return false;
}
return true;
});
print_r($b);
As I understood, yuo want to compare start of string from $b with full string from $a
$b = array_udiff($b, $a,
function($x, $y) { return strcmp(substr($x, 0, strlen($y)), $y); });
demo
Loop through the array and look for match. If doesn't match any elements of the array, then push the value.
$a = ['abc', 'cde', 'efg', 'hi'];
$b = ['bce', 'ifg', 'hig'];
$result = $a;
foreach ($b as $bs) {
$flag = true;
foreach ($a as $as) {
if (strpos($bs, $as) !== false) {
$flag = false;
}
}
if($flag==true)
array_push($result, $bs);
}
return $result;

Not sure what the value of a is

where:
$b = true;
$c = 0;
$a = ($a ? ($a ? $b : $c) : ($c ? $a : $b));
I'm not sure how to work out a.
So I understand that this is a shorthand operator, and usually it's a case of:
$value ? true : false
meaning
if $a = true { true } else { false };
so:
if $a{
if $a{
true;}
else{
0;};
else{
if $0{
$a;}
else{
true;}
};
does this make the value of $a true?
The value of $a would be true
$b = true;
$c = 0;
$a = ($a ? ($a ? $b : $c) : ($c ? $a : $b));
The shorthand can be interpreted like this:
if($a) {
if($a) {
$a = $b;
} else {
$a = $c;
}
} else {
if($c) {
$a = $a;
} else {
$a = $b;
}
}
Because $a is false for not existing in the first place, it immediately jumps to the else statement in that. So the only part that matters to you is:
if($c) {
$a = $a;
} else {
$a = $b;
}
0 is the same as false, so $c will come back as false, therefore $a is equal to $b, which is true.
Edit:
There is some discussion on the notice that is thrown, but this fails to account for the fact that notices are not truly errors and because of this there is no interruption to the code. The result is not Notice: Undefined variable: a, the "result" (think these people mean output) would be blank if it weren't for us determining the value of $a at the end with var_dump. The question was as to what the value of $a becomes, not what appears on your screen.
Something displaying on your screen in re to a variable not being set has nothing to do with the value of what $a is.
If you execute the following code, the notice is not the only thing realized:
$b = true;
$c = 0;
$a = ($a ? ($a ? $b : $c) : ($c ? $a : $b));
var_dump($a);
So the output is:
E_NOTICE : type 8 -- Undefined variable: a -- at line 5
bool(true)
The fact that a notice was thrown does not prevent $a from becoming true.
Also notices are easily suppressed...
error_reporting(0);
$b = true;
$c = 0;
$a = ($a ? ($a ? $b : $c) : ($c ? $a : $b));
var_dump($a);
would result in $a still becoming true, and without seeing the notice.
bool(true)
If you run the code as is, you would get: Notice: Undefined variable: a in myfile.php on line 4
Therefore, I would postulate $a is set somewhere earlier. Yet, whatever value $a has prior, if $a is can be evaluated to true or false, $a would still be true after running your code for the following reason:
If $a were true, then the first part would yield $a = $b and we know $b = true.
if(TRUE) {
if(TRUE) {
$a = $b; //AND $b == TRUE
} else {
$a = $c;
}
} else {
...
}
If $a were false, then the second part would yield $a = $b again
if(FALSE) {
...
} else {
if(0) { // 0 will equate to FALSE
...
} else {
// 0 is the same as FALSE so we end up again with $a = $b
$a = $b; //AND $b == TRUE
}
}
In fact, if you run this code, it will show you the value of $a is true both times:
<?php
$a = false;
$b = true;
$c = 0;
$a = ($a ? ($a ? $b : $c) : ($c ? $a : $b));
echo $a;
$a = true;
$b = true;
$c = 0;
$a = ($a ? ($a ? $b : $c) : ($c ? $a : $b));
echo $a;

Comparing (empty) arrays in PHP

I want to write a test case to make sure a function call sets an array; however, I don't find a way to compare two arrays to make sure two empty arrays are not equal.
// code to be tested (simplified)
$foo = null;
function setFoo($input) {
global $foo;
$foo = array(); // BUG!!! The correct line would be: $foo = $input;
}
// test code
// given
$input = array();
// when
setFoo($input);
// then
if ($foo !== $input) {
// this block is not executed because "array() === array()" => true
throw new Exception('you have a bug');
}
So: What is the proper way to compare two PHP arrays and make sure, they are different instances (no matter if the content is the same)?
Memory locations refers to pointers. Pointers are not available in PHP. References are not pointers.
Anyway, if you want to check if $b is in fact a reference of $a, this is the closest you can get to an actual answer:
function is_ref_to(&$a, &$b) {
if (is_object($a) && is_object($b)) {
return ($a === $b);
}
$temp_a = $a;
$temp_b = $b;
$key = uniqid('is_ref_to', true);
$b = $key;
if ($a === $key) $return = true;
else $return = false;
$a = $temp_a;
$b = $temp_b;
return $return;
}
$a = array('foo');
$b = array('foo');
$c = &$a;
$d = $a;
var_dump(is_ref_to($a, $b)); // false
var_dump(is_ref_to($b, $c)); // false
var_dump(is_ref_to($a, $c)); // true
var_dump(is_ref_to($a, $d)); // false
var_dump($a); // is still array('foo')
I hope this solves your problem.
try this function . Arrays are compared like this with standard comparison operators
function standard_array_compare($op1, $op2)
{
if (count($op1) < count($op2)) {
return -1; // $op1 < $op2
} elseif (count($op1) > count($op2)) {
return 1; // $op1 > $op2
}
foreach ($op1 as $key => $val) {
if (!array_key_exists($key, $op2)) {
return null; // uncomparable
} elseif ($val < $op2[$key]) {
return -1;
} elseif ($val > $op2[$key]) {
return 1;
}
}
return 0; // $op1 == $op2
}

How to assign first non false variable from a group of them

I tried this way without effect:
$a = false;
$b = false;
$c = 'sometext';
$result = $a or $b or $c or exit('error: all variables are false');
and $result should be set to $c, but this gives value of bool(false) instead.
What about:
$result = $a ?: $b ?: $c ?: exit('doh!');
($result = $a) || ($result = $b) || ($result = $c) || exit("no");
or if you want 0 and empty string etc. not count as false:
(($result = $a) !== false) || (($result = $b) !== false) || (($result = $c) !== false) || exit("no");
think about whether this is really readable. You could also use the old fashioned way:
if ($a !== false)
$result = $a;
elseif ($b !== false)
$result = $b;
elseif ($c !== false)
$result = $c;
else
exit("no");
Edit: Just in case you ever need something dynamic ;-).
foreach(array('a','b','c') as $key)
if (($result = $$key) !== false)
break;
if ($result === false)
exit("no");
There's a couple of things going on here:
Firstly, in PHP the result of a boolean operation is a boolean.
Secondly, and more subtly, the "english" boolean operators (or and and) have a low precedence - lower than the assignment operator, =.
Therefore in this expression $result will always get the actual value of $a (regardless of $a's value), since the assignment is applied before the boolean operator.
// This has the same effect:
$result = $a or $b or $c;
// As this:
$result = $a;
$a or $b or $c; // this has no effect
This is confusing, and almost certainly not what you want.
To get the boolean result of whether any of $a, $b, $c is truthy (ie true, or castable to true) you can either use parentheses to force the precedence, or use the "C-style" operators (|| and &&) which have a higher precedence:
// These all have the same effect:
$result = ($a or $b or $c);
$result = $a || $b || $c;
if ($a or $b or $c)
$result = true;
else
$result = false;
if ($a || $b || $c)
$result = true;
else
$result = false;
If you're unsure about operator precedence it's best to use parentheses - they also tend to help make code more readable, since the order of evaluation is made much more obvious.
It's also generally better to not rely on implicit type conversions (especially casting non-numeric strings), since it tends to make for unclear code.
edit:
To answer the actual question, another approach (though I don't really recommend it in this case, since you say you're only interested in the first non-false value) would be to use array_filter without a callback - that would return an array of all the values in the input array that are truthy, with keys preserved.
eg:
$a = false;
$b = false;
$c = 'sometext';
$result = array_filter(array($a, $b, $c));
var_dump($result);
Outputs:
array(1) {
[2]=>
string(8) "sometext"
}
Result of a boolean operator is boolean in php.
$a = false;
$b = false;
$c = 'sometext';
$result = null;
foreach(array('a', 'b', 'c') as $k)
{
if($$k !== false)
{
$result = $$k;
break;
}
}
Also, consider moving your variables into an array.

Categories