PHP - simple condition with parenthesis - php

I have a stupid question about this condition.
Why when I put parenthesis, the result of the condition changes?
$std = new \stdClass();
$std->bool = false;
$resultCond1 = isset($std->bool) and $std->bool == true;
$resultCond2 = (isset($std->bool) and $std->bool == true);
var_dump($resultCond1); // True.
var_dump($resultCond2); // False.

I believe this is due to operator precedence.
Notice in that table that the assignment operators lie firmly between and and &&. Here's what I think is happening:
In the first example, isset is returning true and, prior to the and operation taking place the assignment is happening. After the assignment, the result of the assignment is and'ed and the result of that and operation is then summarily discarded.
In the second example the parentheses dictate that the assignment happens last and so you get the expected result.
You can see this more clearly if you remove the assignment operation altogether and just dump the result of the operations themselves:
var_dump(isset($std->bool) and $std->bool == true); // bool(false)
var_dump((isset($std->bool) and $std->bool == true)); // bool(false)

Both of these conditions are not outputting same result because of operator precedence.
1) For the first one - isset($std->bool) returns true, after that it will check and $std->bool, lastly it will compare that result with true
2) For the second one - it will check isset($std->bool) and $std->bool == true separately. Then compare both of these result.
Second one is more convenient & cleaner way to accomplish this type of work.

Related

Is there some way to get rid of the ugly duplicate mentions of complicated variables in PHP?

I often encounter situations like this:
function stuff()
{
$feed_data = blablabla(...);
if ($feed_data && isset($feed_data['posts'][0]['title']))
return $feed_data['posts'][0]['title'];
return false;
}
As you can see, $feed_data['posts'][0]['title'] is returned, but it's first checked with isset() to make sure it actually exists, which is not guaranteed.
If I do not include the isset() check, it can log even uglier errors about how it doesn't exist. (When things go wrong.)
Now I'm wondering if there is some way to only have to have one instance of the reference sting $feed_data['posts'][0]['title'] in my code, yet also do the check.
This is the most obvious "solution" which I've naturally tested:
$a = $feed_data['posts'][0]['title'];
if ($feed_data && isset($a))
return $a;
However, this will log the error at the first line, because you cannot assign a variable which doesn't exist!
I don't see a way around this, and it's been bothering me for a long time. I hate having duplicate code snippets like that in my code.
It seems like there ought to be a better way.
You can use a null coalescing operator:
$a = $feed_data['posts'][0]['title'] ?? false;
It checks against having a null value, if it does, return false, else return the long variable :)
Note that this was introduced with PHP 7, you can read more here
If you're specifically looking for $feed_data['posts'][0]['title'] then you don't need to check for both this value and the "parent" $feed_data array. Simply check only for this value, as one can not exist without the other.
As mentioned by treyBake you can use the ?? operator (PHP 7+) to place the value in the if statement, when the checks the value as to if the if is executed.
Combining these two points gives:
if($a = $feed_data['posts'][0]['title'] ?? false){
// Do stuff wth $a
return $a;
}
Pre PHP 7:
c'mon, update your system ;-)
NOTE: The result $a needs to be hard checked against false so that falsey values such as 0 or empty strings are not erroneously skipped (If you DO want to skip these falsey things; use empty instead of isset).
if(
($a = isset($feed_data['posts'][0]['title']) ?
$feed_data['posts'][0]['title'] : false) !== false) {
//do stuff with $a
return $a;
}

How you would interpret php assignment statement?

I found an example php assignment statement online which maybe resembles a tertary conditional condensed statement, but not quite. Does anyone have insight as to how to read this assignment statement?
$access = $access || $note->uid == $user->uid && user_access('note resource view own notes');
My first guess was "assign to access whatever is in access, or if empty, whether uid values are equal and'd with the return of user_access." But I get the feeling that is not correct, as it seems illogical.
First have a look at the Operator Precedence
== comes before && comes before || comes before =
Thus your statement is more clear with adding the following parentheses:
$access = (
$access
||
(
($note->uid == $user->uid)
&&
user_access('note')
)
);
assign to access whatever is in access, or if empty,
Not quite: assign to $access the value true* when $access already evaluates to true (true, 1, "some string" etc), or
whether uid values are equal and'd with the return of user_access
Correct
And otherwise assign false. After this statement $access is always either true or false, even when $access === 'yes' before.
Note*: || and && are boolean operators, only capable of 'returning' true or false
I had this exact type of statement in a library way back, and it's basically an elaborate (or maybe just badly-styled?) null-check. Because PHP uses short circuit evaluation, the right-hand side of the or-expression will not evaluate if the left hand one was null.

two equal signs in php when NOT comparing

What do the two equal signs mean when not being used to compare?
$saveOrder = $listOrder == 'a.ordering';
I've never seen anything like this in php.... I am looking at the weblinks Joomla 1.7 admin component.
Thanks
It is used for comparing. Except the result of the comparison is assigned to $saveOrder.
The following code:
<?php
list($listOrder1, $listOrder2) = array('a.ordering', 'a.something_else');
$saveOrder1 = $listOrder1 == 'a.ordering';
$saveOrder2 = $listOrder2 == 'a.ordering';
assigns true to the $saveOrder1 variable and false to the $saveOrder2 variable. If you do not believe, check for yourself here.
They are comparing. It's just not wrapped in parenthesis (like a comparison expression with if/while/etc).
$saveOrder will be assigned either true or false (the result of the condition).
I guess it is the same as $saveOrder = ($listOrder == 'a.ordering');
In your statement also the double equal sign(==) used for the comparison purpose only. Actually your statement contains both the 'assignment'(=) and 'comparison'(==) operators which leads to your confusion.
That is equivalent to $saveOrder = ($listOrder == 'a.ordering');, so first compares the $listOrder with 'a.ordering' and assign the result(true or false) to $saveOrder.
Hope this clear you confusion, if not let me know once.
$listOrder1='a.ordering';
$listOrder1='wrong'
$saveOrder1 = $listOrder1 == 'a.ordering';//1
$saveOrder2 = $listOrder2 == 'a.ordering';//
You can see the output when printing the first will be 1 whereas the second will return: (i.e. nothing)

Question Regarding Variable State in IF Statement

I am a dead beginner with PHP and have been reading through 'PHP for the Web: Visual Quickstart Guide 4th Ed.' by Larry Ullman and have a question regarding something I came across in the book.
At the end of each chapter he has a few questions for review and I am stuck on one of them and not sure if I have the correct answer or the correct train of though regarding it.
The question is as follows:
Without knowing anything about $var will the following conditional be TRUE or FALSE? Why?
if ($var = 'donut') {...
I am apt to say that it will be false because we don't know if $var has been assigned the value donut yet within the program but I am not sure.
Can anyone help explain this to me so I can grasp this concept and feel confident about it?
There is only one equal sign so it will return true. Heres why: It is assigning "donut" to $var which makes $var true. :)
If the statement had 2 or 3 equal signs we wouldn't know what it would return.
It will be true since the $var variable is define to be 'donut', if the $var variable is empty then it should be returning false.
Example
$var = ''; // False
$var = 'something something'; //True
This conditional will always evaluate to TRUE because the value donut is assigned, and then the value of $var is returned to the if() statement. The assignment happens first.
A successful assignment to a variable causes that variable to be returned immediately. A non-empty string is a "truthy" value, and is returned as such.
If instead it was assigned as:
if ($var = "") {}
It would evaluate to FALSE, according to PHP's boolean evaluation rules:
var_dump((bool) ""); // bool(false)
var_dump((bool) 1); // bool(true)
var_dump((bool) -2); // bool(true)
var_dump((bool) "foo"); // bool(true)
var_dump((bool) 2.3e5); // bool(true)
var_dump((bool) array(12)); // bool(true)
var_dump((bool) array()); // bool(false)
var_dump((bool) "false"); // bool(true)
Addendum
Just to add, as a practical example of assignment inside a flow control conditional you probably see almost every day -- the while() loop we typically use to retrieve a rowset from a MySQL result resource:
while ($row = mysql_fetch_assoc($result)) {
// executes this inner block as long as $row doesn't
// recieve a FALSE assignment from mysql_fetch_assoc()
// reaching the end of its rowset
}
it will be true as $var = 'donut' is an assignment and not 'is equals to (==)'. The = operator assigns the value of the right hand side to the variable on the left hand side.The == operator checks whether the right hand side is equal to the left hand side.
To make things simpler here is a better explanation.
<?php
// To assign a value to a variable you do this
$var = 'donut';
// To evalute the value of a variable you do this.
if($var == 'donut') { }
// Notice the existence of double equals here.
// If you have code like this:
$var = 'donut holes';
if ($var = 'donut') {
// This is true because any value you assign with ONE equals is always TRUE
print $var; // Will output 'donut' because you reassigned it.
}

A php if statement with one equal sign...? What does this mean?

I'm attempting to troubleshoot a problem, and need to understand what this if statement is saying:
if ($confirmation = $payment_modules->confirmation()) {
All the resources I can find only show if statements with double equal signs, not single. Is this one of the shorthand forms of a php if? What is it doing?
(If it's actually wrong syntax, changing it to a double equal sign doesn't resolve the problem. As-is, in some scenarios it does return true. In the scenario I'm troubleshooting, it doesn't return true until after I refresh the browser.)
Any help is greatly appreciated!!!
It's a form of shorthand, which is exactly equivalent to this:
$confirmation = $payment_modules->confirmation();
if ($confirmation) {
}
This will first assign the value of $payment_modules->confirmation() to $confirmation. The = operator will evaluate to the new value of $confirmation.
This has the same effect as writing:
$confirmation = $payment_modules->confirmation();
if ($confirmation) {
// this will get executed if $confirmation is not false, null, or zero
}
The code works because an assignment returns the value assigned, so if $payment_modules->confirmation() is true, $confirmation will be set to true, and then the assignment will return true. Same thing for false.
That's why you can use a command to assign to many variables, as in a = b = 0. Assigns zero to b and returns that zero. Therefore, it becomes a = 0. And a receives zero and it will return that zero, which can or can not be used.
Sometimes people like to do an assignment and then check if the assignment went through okay. Pair this up with functions that return false (or equivalent) on failure, and you can do an assignment and a check at the same time.
In order to understand this, remember that assignments are a kind of expression, and so (like all expressions) have a return value. That return value is equal to whatever got put into the variable. That is why you can do something like
a = b = c = 0;
to assign all of those variables at the same time.
= means assignment ( $a = 1 ), == is for comparison ( true == false is false ). I think in your example it should use = because it assigns it to the return value of confirmation, which should be something that evaluates to true.
Try doing a var_dump:
var_dump( $payment_modules->confirmation() );
See what boolean it evaluates to, and from there you can troubleshoot. Post more code if you want more help.
class test() {
public function confirmation() { return true; }
}
$boolean = test::confirmation();
var_dump( $boolean );
Will equate to true

Categories