-1

Someone wrote this 'stunning' short hand encapsulated statement. I am sure its not even suppose to be done like this, but I want to dissect it for someone else (myself as well) to be able to understand it well by break it down into if and else statement. I wonder where exactly is the way it should be broke down the statement with. the ? and : position really confused me and make me can get down to nowhere! (i.e. there is ? after another ? how that could be?

$cust->is_company() ? 'TekCustomer__'.($cust->getID() ? $cust->getID() : 'new'.($next_new_id-1)) : 'Person__'.($cust->people[0]->getID() ? $cust->people[0]->getID() : 'new'.$next_new_id++) 
Ezeewei
  • 6,347
  • 7
  • 50
  • 98
  • It's a lot of ternary operators. `($statement ? true : false)` They are nested inside of each other – Rimble Oct 21 '14 at 13:57
  • Check [ternary operators](http://php.net/manual/en/language.operators.comparison.php#language.operators.comparison.ternary) its syntax and just dissect all operators one by one. – Elias Oct 21 '14 at 13:59
  • possible duplicate of [Reference - What does this symbol mean in PHP?](http://stackoverflow.com/questions/3737139/reference-what-does-this-symbol-mean-in-php) – Michael Sivolobov Oct 21 '14 at 19:23
  • @MichaelSivolobov so, I guess you expect people to looking for specific question in that big sheet of answers which that may point out the answer which may not even in the same scenario? Dont know how it is duplicated by elaborating a topic. – Ezeewei Oct 21 '14 at 20:47

6 Answers6

1

You'll probably find it more readable like this :

$cust->is_company() ?
  'TekCustomer__' . ( $cust->getID() ? $cust->getID() : 'new'.($next_new_id-1) )
:
  'Person__' . ( $cust->people[0]->getID() ? $cust->people[0]->getID() : 'new'.$next_new_id++)

Basically it checks if it is a company :

  • Yes : it builds a string TekCustomer__ with the current ID of customer if it exists. If not it seems to generate a new id.
  • No : it builds a string Person__ with the current ID of a customer people if it exists. If not it seems to generate a new id.
ForguesR
  • 3,323
  • 1
  • 14
  • 32
1

This is how it should probably be extended. It is called a ternary operator.

$statement ? value_if_true : value_if_false.

if($cust->is_company()) 
{
    $string = 'TekCustomer__';

    if($cust->getId()) 
    {
        $string .= $cust->getID();  
    } 
    else 
    {
        $string .= 'new'.($next_new_id-1));
    }
} 
else 
{
    $string = 'Person__';

    if($cust->people[0]->getID())
    {
        $string .= $cust->people[0]->getID();
    } 
    else 
    {
        $string .= 'new'.$next_new_id++;
    }
}
Artur K.
  • 2,970
  • 3
  • 35
  • 50
1

I would highly recommend against the use of nested ternary operators. As you have found out they are far from readable. Converting to proper if statements here will certainly make it more readable. We can start by formatting it a bit to help break it down:

$cust->is_company() ? 
    'TekCustomer__'.($cust->getID() ? $cust->getID() : 'new'.($next_new_id-1)) :
     'Person__'.($cust->people[0]->getID() ? $cust->people[0]->getID() : 'new'.$next_new_id++)

Aha! It's actually not quote as horrible as it first looks (especially due to PHP's odd behaviour on nested ternarys*).

First off it's checking $cust->is_company() and doing one of two things. This gives us:

if($cust->is_company()){
    'TekCustomer__'.($cust->getID() ? $cust->getID() : 'new'.($next_new_id-1));
}else{
    'Person__'.($cust->people[0]->getID() ? $cust->people[0]->getID() : 'new'.$next_new_id++)
}

Note here that generally you would do something with the values. This will depend on how the expression was originally used.

I'll leave the inner ternarys as an exercise for the reader!

*PHP resolves nested ternary operators left to right rather than right to left. See http://php.net/manual/en/language.operators.comparison.php

Jim
  • 21,521
  • 5
  • 49
  • 80
0

I have no idea what each variable holds but this is a way to deconstruct it.

if($cust->is_company())
{
    echo 'TekCustomer__';
    if($cust->getID())
    {
        echo $cust->getID();
    }else
    {
        echo 'new'.$next_new_id-1;
    }
}else
{
    echo 'Person__';
    if($cust->people[0]->getID())
    {
        echo $cust->people[0]->getID();
    }else
    {
        echo 'new'.$next_new_id++;
    }
}
Rimble
  • 863
  • 8
  • 21
0
if ($cust->is_company())
    if ($cust->getID())
        return 'TekCustomer__' . $cust->getID();
    else
        return 'TekCustomer__new'.($next_new_id-1);
else
   if ($cust->people[0]->getID())
        return 'Person__' . $cust->people[0]->getID();
   else 
        return 'Person__new'.$next_new_id++);
Sal00m
  • 2,884
  • 3
  • 19
  • 32
0

It looks like this is a statement on the right hand side of an assignment. So, we would need to have a variable to build the string, and then just break it down by parentheses:

$tmp = '';
if ($cust->is_company()) { // first '?'
    $tmp .= 'TekCustomer__';
    if ($cust->getID()) { // second '?'
        $tmp .= $cust->getID();
    } else {
        $tmp .= 'new' . ($next_new_id - 1);
    } 
} else { 
    $tmp .= 'Person__'; 
    if ($cust->people[0]->getID()) { // third '?'
        $tmp .= $cust->people[0]->getID();
    } else { 
        $tmp .= 'new' . $next_new_id++;
    }
}