views:

179

answers:

3

Hi i was recently looking over a shopping cart paginator class, trying to understand their code so i could build my own paginator when i came across the following line of code. It resembles a ternary statement but is written in a way that i have never seen before. I would google it but i wouldn't know what to google. Could someone please tell me what this is how it works and what it is called so i can do a search for it and learn more.

    return ($output ? '<div class="' . $this->style_links . '">' . $output . '</div>' : '') 
. '<div class="' . $this->style_results . '">' . sprintf($this->text, ($total) ? (($page - 1) * $limit) + 1 : 0, ((($page - 1) * $limit) > ($total - $limit)) ? $total : ((($page - 1) * $limit) + $limit), $total, $num_pages) . '</div>';

Just let me know if this is enough code to go on Thanks Andrew

+1  A: 
expression ? runs if true : runs if false;

More here

 http://www.johnhok.com/2008/02/23/php-tip-tertiary-operator/

In your case:

$output ? '<div class="' . $this->style_links . '">' . $output . '</div>' : ''

If $output variable is not empty then following is return otherwise empty '' string is returned.

<div class="' . $this->style_links . '">' . $output . '</div>'

Same is the case with other tertiary operators used in your code.

Sarfraz
ok so if you just put a variable you are saying is this variable empty. I didn't realise you could use them this way
andrew
yes $output ? is same as if ($output != '')
Sarfraz
do you mean ($output == '' ) ? ie output is equal to nothing?
andrew
No. Just having `$output` as the condition is the equivalent of testing that it is *not* equal to nothing...
Franz
+2  A: 

Nice... It is just a regular conditional operator (well, 3 of them, along with some concatenation).

If you reformat it, it gets a bit clearer:

$output = $output ? '<div class="' . $this->style_links . '">' . $output . '</div>' : '';

$min = $total ? (($page - 1) * $limit) + 1 : 0;
$max = (($page - 1) * $limit) > ($total - $limit) ? $total : ((($page - 1) * $limit) + $limit);

$output .= '<div class="' . $this->style_results . '">'
    . sprintf($this->text, $min, $max, $total, $num_pages)
    . '</div>';

return $output;
Greg
Ok, i don't understand the first line. What does the question mark mean there i thought ternary operators went like this$string = (condtion)?do if true:do if false;where is the condition? or is output the condition, how can it be the condition?
andrew
I haven't seen them used in this way before, how does that work
andrew
A simple variable is an expression, too. This does return true if the variable's value "equals" true, so it should not be `0`, `false`, `array()` or an empty string...
Franz
It's like using an `if ()`: `if ($output)` is the same as `if ($output == true)` - in the same way `$output ? x : y` is the same as `$output == true ? x : y`
Greg
+1  A: 

It is called conditional operator and I would consider this to be an abuse of it. Conditional operators can be useful in reducing short if-else constructs into one statement without effecting the readability of the code.

if(a == b)
    c = d;
else
    c = e;
//can be written as:
c = a == b ? d : e;

The given code can be written as:

return ($output ? 
            '<div class="' . $this->style_links . '">' . $output . '</div>'
         : '') . 
    '<div class="' . $this->style_results . '">' . 
    sprintf($this->text, 
        ($total) ? 
            (($page - 1) * $limit) + 1 
          : 0, 
        ((($page - 1) * $limit) > ($total - $limit)) ? 
            $total 
          : ((($page - 1) * $limit) + $limit), 
        $total, $num_pages) . '</div>';

And is equivalent to:

if($output)
    $str = '<div class="' . $this->style_links . '">' . $output . '</div>';
else
    $str = '';

$str .= '<div class="' . $this->style_results . '">';

if($total)
    $first = (($page - 1) * $limit) + 1;
else
    $first = 0;

if((($page - 1) * $limit) > ($total - $limit))
    $second = $total;
else
    $second = ((($page - 1) * $limit) + $limit);

$str .= sprintf($this->text, $first, $second, $total, $num_pages);
$str .= '</div>';
Amarghosh
except in their case it is just$a = $b?c:d; which i thought was weird because i didn't realise that you could test a variable for being empty without using empty($var)
andrew
`if($output)` evaluates to `true` if `$output` is defined somewhere before and is not an empty string. Empty strings are `false`.
Amarghosh
ahhh ok that makes sense. Thanks
andrew
" When converting to boolean, the following values are considered FALSE: * the boolean FALSE itself * the integer 0 (zero) * the float 0.0 (zero) * the empty string, and the string "0" * an array with zero elements * an object with zero member variables (PHP 4 only) * the special type NULL (including unset variables) * SimpleXML objects created from empty tags "http://www.php.net/manual/en/language.types.boolean.php#language.types.boolean.castingAs a reference for people who might come across this question while searching :)
Duroth