assignment in PHP - php

I am learning php and read this example in this http://www.php.net/manual/en/language.types.boolean.php tutorial,
I want to understand what occur when assigning the return value of method to a variable, why it may change?? please see my questions in the code.
<?php
public function myMethod()
{
return 'test';
}
public function myOtherMethod()
{
return null;
}
if($val = $this->myMethod())
{
// $val might be 1 instead of the expected 'test'
** why it may returns 1??**
}
if( ($val = $this->myMethod()) )
{
// now $val should be 'test'
}
// or to check for false
if( !($val = $this->myMethod()) ) **what happens here????**
{
// this will not run since $val = 'test' and equates to true
}
// this is an easy way to assign default value only if a value is not returned:
if( !($val = $this->myOtherMethod()) ) **what happens here????**
{
$val = 'default'
}
?>

In this case:
if($val = $this->myMethod())
{
// $val might be 1 instead of the expected 'test'
}
I don't think that's true. $val should be 'test' here. Maybe in older versions of PHP there could have been a bug.
if(!($val = $this->myMethod()))
{
// this will not run since $val = 'test' and equates to true
}
Here myMethhod() is executed and returns 'test' which is assigned to $val. Then the result of that assignment is boolean negated. Since the string 'test' evaluates to true, !('test') evalutes to false and the if statement doesn't run.
if(!($val = $this->myOtherMethod()))
{
$val = 'default';
}
This is the opposite case. $val becomes null. And null evaluates to boolean false, so !(null) evaluates to true and the code in the block executes. So after this code runs $val contains 'default'; This poster is showing this as a way of assigning a default value to $val in the case that $this->myOtherMethod() fails to return anything useful.

why it may returns 1? It is not returning 1 but the actual value that is 'test' but since this value is assigned properly because this is not NULL, false or empty. the if statement evaluates to true.
// or to check for false
if( !($val = $this->myMethod()) ) **what happens here????**
{
// this will not run since $val = 'test' and equates to true
}
What is happening here? The if statement here will test if non NULL value has been assigned to $val i.e. $val is not null similar to if(!$val). Since its value is not NULL nor false The code inside if will not execute.
if( !($val = $this->myOtherMethod()) ) **what happens here????**
{
$val = 'default'
}
What is happening here? since the assignment to the $val inside if statement failed because function returned NULL, and since $val is NULL if statement evaluates true and code inside executes. It wouldn't execute if the function had returned other than NULL or false.

Sorry guys, but i think the previous answers are wrong. I'm not sure if this is a typo or a trick question, but with
if($val = $this->myMethod())
you're actually SETTING $val to whatever $this->myMethod() returns, so your if() statement always equals true here. if you want to compare it you would have to use
if($val == $this->myMethod())
Notice the '==' in here!

Try This:
public function myMethod()
{
return 'test';
}
public function myOtherMethod()
{
return null;
}
if($val = myMethod())
{
Do Something
}elseif ($val != myMethod()){
Do Something Else
}elseif ($val == myOtherMethod())
{
$val = 'default';
}
?>

Related

Boolean has wrong value after operation [duplicate]

I remember reading a while back in regards to logical operators that in the case of OR, using || was better than or (or vice versa).
I just had to use this in my project when it came back to me, but I can't remember which operator was recommended or if it was even true.
Which is better and why?
There is no "better" but the more common one is ||. They have different precedence and || would work like one would expect normally.
See also: Logical operators (the following example is taken from there):
// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;
// The constant false is assigned to $f and then true is ignored
// Acts like: (($f = false) or true)
$f = false or true;
They are used for different purposes and in fact have different operator precedences. The && and || operators are intended for Boolean conditions, whereas and and or are intended for control flow.
For example, the following is a Boolean condition:
if ($foo == $bar && $baz != $quxx) {
This differs from control flow:
doSomething() or die();
The difference between respectively || and OR and && and AND is operator precedence :
$bool = FALSE || TRUE;
interpreted as ($bool = (FALSE || TRUE))
value of $bool is TRUE
$bool = FALSE OR TRUE;
interpreted as (($bool = FALSE) OR TRUE)
value of $bool is FALSE
$bool = TRUE && FALSE;
interpreted as ($bool = (TRUE && FALSE))
value of $bool is FALSE
$bool = TRUE AND FALSE;
interpreted as (($bool = TRUE) AND FALSE)
value of $bool is TRUE
Source: http://wallstreetdeveloper.com/php-logical-operators/
Here is sample code for working with logical operators:
<html>
<head>
<title>Logical</title>
</head>
<body>
<?php
$a = 10;
$b = 20;
if ($a>$b)
{
echo " A is Greater";
}
elseif ($a<$b)
{
echo " A is lesser";
}
else
{
echo "A and B are equal";
}
?>
<?php
$c = 30;
$d = 40;
//if (($a<$c) AND ($b<$d))
if (($a<$c) && ($b<$d))
{
echo "A and B are larger";
}
if (isset($d))
$d = 100;
echo $d;
unset($d);
?>
<?php
$var1 = 2;
switch($var1)
{
case 1: echo "var1 is 1";
break;
case 2: echo "var1 is 2";
break;
case 3: echo "var1 is 3";
break;
default: echo "var1 is unknown";
}
?>
</body>
</html>
I know it's an old topic but still. I've just met the problem in the code I am debugging at work and maybe somebody may have similar issue...
Let's say the code looks like this:
$positions = $this->positions() || [];
You would expect (as you are used to from e.g. javascript) that when $this->positions() returns false or null, $positions is empty array. But it isn't. The value is TRUE or FALSE depends on what $this->positions() returns.
If you need to get value of $this->positions() or empty array, you have to use:
$positions = $this->positions() or [];
EDIT:
The above example doesn't work as intended but the truth is that || and or is not the same... Try this:
<?php
function returnEmpty()
{
//return "string";
//return [1];
return null;
}
$first = returnEmpty() || [];
$second = returnEmpty() or [];
$third = returnEmpty() ?: [];
var_dump($first);
var_dump($second);
var_dump($third);
echo "\n";
This is the result:
bool(false)
NULL
array(0) {
}
So, actually the third option ?: is the correct solution when you want to set returned value or empty array.
$positions = $this->positions() ?: [];
Tested with PHP 7.2.1
I don't think one is inherently better than another one, but I would suggest sticking with || because it is the default in most languages.
EDIT: As others have pointed out there is indeed a difference between the two.
There is nothing bad or better, It just depends on the precedence of operators. Since || has higher precedence than or, so || is mostly used.
Some languages use short-circuit, and others use full Boolean evaluation (if you know, this is similar to the directive $B in Pascal).
Explanations:
function A(){
...Do something..
return true;
}
function B(){
...Do something..
return true;
}
if ( A() OR B() ) { .....
In this example the function B() will never be executed. Since the function A() returns TRUE, the result of the OR statement is known from the first part without it being necessary to evaluate the second part of the expression.
However with ( A() || B() ), the second part is always evaluated regardless of the value of the first.
For optimized programming, you should always use OR which is faster (except for the case when the first part returns false and second part actually needs to be evaluated).

Make the function return 0 and store it in a variable

Seems super trivial, but can't find a solution to this specific case on SO
A function may return a value of 0 OR another number, which I then want to store in a variable $s to calculate stuff. But can't find a clean way of doing it.
So for example:
function f() {
$v = "0";
return $v;
}
if($s = f() !== false) {
echo $s;
// ^ I want 0, but the value above is 1 (since it's true)
}
I tried returning it as a string
return "0" instead of a digit, but it doesn't work.
If I do this it will not evaluate to true so nothing will happen
if($s = f()) {
// returns nothing
}
But when I var_dump(f()), it does show string '0' (length=1)
So I can do
if(var_dump(f()) == 0)
OR
if(f() == 0)
But is there not a cleaner way to do it, so the function may return 0 or another number and I can just capture it in a variable?
Add parentheses:
if (($s = f()) !== false) {
Otherwise you're computing the value f() !== false and assigning it to $s, instead of assigning f() to $s and then comparing to false.
First
if($s = f() !== false) {
echo $s;
// ^ I want 0, but the value above is 1 (since it's true)
}
Whats happening here is return value of f() is strictly compared to false, that is, "0" is compared to false. They are not strictly equal, hence f() !== false returns true, which is stored in $s as 1.
Next,
if($s = f()) {
// returns nothing
}
This doesnt enter the if block because $s contains "0" and it is loosely equal to false.
Next
if(var_dump(f()) == 0) or if(f() == 0)
this works because it is loosely comparing "0" to 0 which is true. Hence it enters the block.
Remember, if condition does loose comparision or == and === does strict comparision. More about it here.
So, this should work in your case
if(($s = f()) !== 0)
if f() returns integers
Try some parenthesis:
if(($s = f()) !== false) {
To force $s to equal f(), not f() !== false

check for empty value in php

I am checking a value to see if it is empty using the empty() function in PHP. This validates the following as empty:
"" (an empty string)
0 (0 as an integer)
0.0 (0 as a float)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
$var; (a variable declared, but without a value)
The value I am passing can be a string, array or number. However if a string has a space (" ") it is not considered empty. What is the easiest way to check this condition as well without creating my own function? I cannot just do an empty(trim($value)) since $value can be an array.
EDIT: I am not trying to ask how to check if a string is empty. I already know that. I am asking if there is a way that I can pass an array, number or string to empty() and it will return the correct validation even if the string passed has empty spaces in them.
Just write an own isEmpty() function that fits your needs.
function isEmpty($value) {
if(is_scalar($value) === false)
throw new InvalidArgumentException('Please only provide scalar data to this function');
if(is_array($value) === false) {
return empty(trim($value));
if(count($value) === 0)
return true;
foreach($value as $val) {
if(isEmpty($val) === false)
return false;
}
return false;
}
The best way is to create your own function, but if you really have a reason not to do it you can use something like this:
$original_string_or_array = array(); // The variable that you want to check
$trimed_string_or_array = is_array($original_string_or_array) ? $original_string_or_array : trim($original_string_or_array);
if(empty($trimed_string_or_array)) {
echo 'The variable is empty';
} else {
echo 'The variable is NOT empty';
}
I really prefer the function TiMESPLiNTER made, but here is an alternative, without a function
if( empty( $value ) or ( !is_array( $value ) and empty( trim( $value ) ) ) ) {
echo 'Empty!';
}
else {
echo 'Not empty!';
}
Note that, for example $value = array( 'key' => '' ) will return Not empty!. Therefor, I'd suggest to use TiMESPLiNTERs function.

PHP variable declaration shorthand (similar to JavaScript)

In JavaScript, I can do this:
var somevar = {
propertyTwo : false,
propertyThree : "hello!"
}
var test = somevar.propertyOne || somevar.propertyTwo || somevar.propertyThree
alert(test); //displays "hello!"
Is there a similar functionality in PHP for this?
Haven't been able to find anything online.
I tried this, but PHP just treats it like a comparison and echo's 1 (true)
$somevar = array(
'propertyTwo' => false,
'propertyThree' => "hello!"
);
$test = $somevar['propertyOne'] || $somevar['propertyTwo'] || $somevar['propertyThree'];
echo $test; //displays '1'
Not really a big deal if there isn't, but I figured that with all of the bells and whistles provided in php 5.x, there would be some kind of shorthand for assigning the first true value in a list of values to a single variable like that.
I suppose I could write a function.
EDIT :
As I suspected, PHP doesn't have the same quirk.
Quick function I wrote
function assign_list($list){
foreach($list as $v)
if(isset($v) && $v) return $v;
return false;
}
Just pass it an array of stuff
The following will work in PHP >= 5.3, but you will still receive a Notice Error because propertyOne is not defined.
<?php
$somevar = array(
'propertyTwo' => false,
'propertyThree' => "hello!"
);
$test = $somevar['propertyOne'] ?: $somevar['propertyTwo'] ?: $somevar['propertyThree'];
echo $test; //displays 'hello!'
You could however work around this by supressing the variables, but it is highly unrecommended:
$test = #$somevar['propertyOne'] ?: #$somevar['propertyTwo'] ?: #$somevar['propertyThree'];
This doesn't work in PHP, and here's why:
$somevar['propertyOne'] = false;
$somevar['propertyTwo'] = true;
$test = $somevar['propertyOne'] || $somevar['propertyTwo'];
Imagine typing that query into an if statement:
if( $somevar['propertyOne'] || $somevar['propertyTwo'] ){ ... }
This will return true (evaluates to 1) if either variable is true.
Now, if we make all of the variables = false:
$somevar['propertyOne'] = false;
$somevar['propertyTwo'] = false;
$test = $somevar['propertyOne'] || $somevar['propertyTwo'];
The variable returns false (evaluates to 0).
Another thing we can do is:
$somevar['propertyOne'] = true;
$somevar['propertyTwo'] = true;
$test = $somevar['propertyOne'] && $somevar['propertyTwo'];
This will return true (evaluates to 1) as both variables meet the criteria.
This means that we can do things like this in PHP though:
$test = $somevar['propertyOne'] || $somevar['propertyTwo'];
if($test){ ... }
TL,DR: In PHP you are storing the result of the expression into a variable, not doing any validation on anything.

Logical Operators, || or OR?

I remember reading a while back in regards to logical operators that in the case of OR, using || was better than or (or vice versa).
I just had to use this in my project when it came back to me, but I can't remember which operator was recommended or if it was even true.
Which is better and why?
There is no "better" but the more common one is ||. They have different precedence and || would work like one would expect normally.
See also: Logical operators (the following example is taken from there):
// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;
// The constant false is assigned to $f and then true is ignored
// Acts like: (($f = false) or true)
$f = false or true;
They are used for different purposes and in fact have different operator precedences. The && and || operators are intended for Boolean conditions, whereas and and or are intended for control flow.
For example, the following is a Boolean condition:
if ($foo == $bar && $baz != $quxx) {
This differs from control flow:
doSomething() or die();
The difference between respectively || and OR and && and AND is operator precedence :
$bool = FALSE || TRUE;
interpreted as ($bool = (FALSE || TRUE))
value of $bool is TRUE
$bool = FALSE OR TRUE;
interpreted as (($bool = FALSE) OR TRUE)
value of $bool is FALSE
$bool = TRUE && FALSE;
interpreted as ($bool = (TRUE && FALSE))
value of $bool is FALSE
$bool = TRUE AND FALSE;
interpreted as (($bool = TRUE) AND FALSE)
value of $bool is TRUE
Source: http://wallstreetdeveloper.com/php-logical-operators/
Here is sample code for working with logical operators:
<html>
<head>
<title>Logical</title>
</head>
<body>
<?php
$a = 10;
$b = 20;
if ($a>$b)
{
echo " A is Greater";
}
elseif ($a<$b)
{
echo " A is lesser";
}
else
{
echo "A and B are equal";
}
?>
<?php
$c = 30;
$d = 40;
//if (($a<$c) AND ($b<$d))
if (($a<$c) && ($b<$d))
{
echo "A and B are larger";
}
if (isset($d))
$d = 100;
echo $d;
unset($d);
?>
<?php
$var1 = 2;
switch($var1)
{
case 1: echo "var1 is 1";
break;
case 2: echo "var1 is 2";
break;
case 3: echo "var1 is 3";
break;
default: echo "var1 is unknown";
}
?>
</body>
</html>
I know it's an old topic but still. I've just met the problem in the code I am debugging at work and maybe somebody may have similar issue...
Let's say the code looks like this:
$positions = $this->positions() || [];
You would expect (as you are used to from e.g. javascript) that when $this->positions() returns false or null, $positions is empty array. But it isn't. The value is TRUE or FALSE depends on what $this->positions() returns.
If you need to get value of $this->positions() or empty array, you have to use:
$positions = $this->positions() or [];
EDIT:
The above example doesn't work as intended but the truth is that || and or is not the same... Try this:
<?php
function returnEmpty()
{
//return "string";
//return [1];
return null;
}
$first = returnEmpty() || [];
$second = returnEmpty() or [];
$third = returnEmpty() ?: [];
var_dump($first);
var_dump($second);
var_dump($third);
echo "\n";
This is the result:
bool(false)
NULL
array(0) {
}
So, actually the third option ?: is the correct solution when you want to set returned value or empty array.
$positions = $this->positions() ?: [];
Tested with PHP 7.2.1
I don't think one is inherently better than another one, but I would suggest sticking with || because it is the default in most languages.
EDIT: As others have pointed out there is indeed a difference between the two.
There is nothing bad or better, It just depends on the precedence of operators. Since || has higher precedence than or, so || is mostly used.
Some languages use short-circuit, and others use full Boolean evaluation (if you know, this is similar to the directive $B in Pascal).
Explanations:
function A(){
...Do something..
return true;
}
function B(){
...Do something..
return true;
}
if ( A() OR B() ) { .....
In this example the function B() will never be executed. Since the function A() returns TRUE, the result of the OR statement is known from the first part without it being necessary to evaluate the second part of the expression.
However with ( A() || B() ), the second part is always evaluated regardless of the value of the first.
For optimized programming, you should always use OR which is faster (except for the case when the first part returns false and second part actually needs to be evaluated).

Categories