1

I wasn't even sure how to Google this. How would this PHP statement be written longform?

$recentlyViewed = $products = $this->getRecentlyViewedProducts();

Optimizations like this make experts feel smart, and beginners feel really stupid. I'm pretty sure I understand what the outcome is, but maybe I'm wrong.

A: Is this equivalent?

$products = $this->getRecentlyViewedProducts();
$recentlyViewed = ($products) ? true : false;

B: Is this equivalent?

$products = $this->getRecentlyViewedProducts();
$recentlyViewed = $products;

Which is right?

Via Twitter, seems B is equivalent.

Public Service Announcement

Write glaringly simple code. Don't be clever.

Brendan Falkowski
  • 733
  • 1
  • 5
  • 17
  • `$products = $this->getRecentlyViewedProducts(); $recentlyViewed = $products;` – Tintu C Raju Dec 02 '15 at 05:23
  • If you want to assign the `$this->getRecentlyViewedProducts()` if it's not empty you may do it this way: `$recentlyViewed = $this->getRecentlyViewedProducts() ? : 'other_value';` Here omitting second argument means that the first one will be assigned if it evaluates to true. Otherwise, the 'other_value' will be assigned. Have in mind that it will work only if the method returns empty array or null/false/0/empty string if there are no recently viewed. If it returns, e.g. a collection object it would evaluate to true, even if it's actually empty. – Lanius Dec 02 '15 at 08:02

3 Answers3

2
$recentlyViewed = $products = $this->getRecentlyViewedProducts();

And

$products = $this->getRecentlyViewedProducts();
$recentlyViewed = ($products) ? true : false;

I think this is equivalent:

Nope its not equivalent.

Let's see the difference

$recentlyViewed = $products = range(1,10);

So if you print_r then the value'll be

print_r($recentlyViewed);
print_r($products);

This'll print two arrays from [1,2,3,....10] but the

$products = range(1,10);
$recentlyViewed = ($products) ? true : false;

So if you print the $products and $recentlyViewed then the result will be the first'll print an array and the other one'll print 1.

So whats the equivalent of

$recentlyViewed = $products = $this->getRecentlyViewedProducts();

will be

$products = $this->getRecentlyViewedProducts();
$recentlyViewed = $products;

Demo

Narendrasingh Sisodia
  • 21,247
  • 6
  • 47
  • 54
1

The equivalent is this

$products = $this->getRecent();
$recentlyViewed = $products;

I'm not sure how a test for $products would make sense there as the double assignment does not return booleans.

See here the difference between raw types and objects.
Are multiple variable assignments done by value or reference?

Community
  • 1
  • 1
Alex Andrei
  • 7,315
  • 3
  • 28
  • 42
  • You're right about the double assignment. This is confusing for beginners because it's common to see non-explicit ternaries like: $x = $y === 1; That's a hard harder to understand than something explicit like: $x = ($y === 1) ? true : false; Hence my confusion with the above and not recognizing the assignment behaves differently than a comparison operator. – Brendan Falkowski Dec 02 '15 at 05:31
  • first of all there are no "ternaries" plural in PHP :) As far as I know there is only one ternary operator, the short-hand `if`,it's called ternary because it takes 3 operands, the condition and two results, one for `true` and one for `false`. – Alex Andrei Dec 02 '15 at 05:41
0

When you write:

$recentlyViewed = $products = $this->getRecentlyViewedProducts();

what PHP does is that begging from the right hand and assigns most right value to the left side variable (if any). This value can be a const value (i.e. string or number), another variable or return value of a function ($this->getRecentlyViewedProducts() in this case). So here are steps:

  • calculate return value of ($this->getRecentlyViewedProducts()in this case)
  • assign calculated value to $products
  • assign $product to $recentlyViewed

so if we assume your getRecentlyViewedProducts function returns 'Hello Brendan!', at the end of execution, both $products and $recentlyViewed would have same value.

In PHP, variable types are implicit and therefore you can use them directly in if statements like this:

if($recentlyViewed) { ... }

and in this case if $recentlyViewed is setted and its value $recentlyViewed is anything other that 0, false or null, your if condition will satisfy.
It's very common to use non-boolean values in PHP as check conditions, anyway if you are using $recentlyViewed just as a flag, it's better to do this for the sake of code readability and memory optimization (attention that if your function returns for example a large string, copying its value in a separate variable to use it as just a flag is not a wise choice):

$recentlyViewed = $products ? true : false;

or

$recentlyViewed = $products ? 1 : 0;

althogh the result would not be different.

Ehsan Khodarahmi
  • 4,772
  • 10
  • 60
  • 87