0

Does anybody know if there is a shortcut for the following statement in PHP?

$output = isset($some_value) ? $some_value : "Some Value Not Set";
echo $output;

This something that I often run into, where $some_value is actually very long and possibly involves a function, such as:

$output = $this->db->get_where('my_db',array('id'=>$id))->row()->some_value) ? $this->db->get_where('my_db',array('id'=>$id))->row()->some_value) : "Some Value Not Set";
echo $output;

It seems that there should be an operator or function that does this. I could easily write one, and I am not looking for that answer, but rather if anybody knows of a built-in shortcut.

innaM
  • 47,505
  • 4
  • 67
  • 87
chaimp
  • 16,897
  • 16
  • 53
  • 86
  • 3
    Please see http://stackoverflow.com/questions/1080247/what-is-the-php-operator-called-and-what-does-it-do/1080256#1080256. – chaos Oct 15 '09 at 18:47

6 Answers6

9

Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.

http://php.net/manual/en/language.operators.comparison.php

chelmertz
  • 20,399
  • 5
  • 40
  • 46
  • 4
    Wow, Zend's stupidity finally comes full circle. In their ignorance they called the conditional operator "the ternary operator" in their documentation, and now they've implemented a form of it where **IT IS A BINARY OPERATOR NOT A TERNARY ONE**. It's like Christmas for irony. – chaos Oct 15 '09 at 18:49
  • Despite the naming issue, that is the sort of functionality that I am looking for, but I guess it is relatively "new" to PHP. – chaimp Oct 15 '09 at 18:58
  • i guess if there is only one ternary operator in a language, calling it "the (php) ternary operator" is not completely wrong. also, considering that "expr1 ?: expr3" is just syntactic sugar for "expr1 ? expr1 : expr3", with the first expr1 being evaluated boolean and the second "by value", and that this is being used a lot of times, i wouldn't be so strict about calling it binary operator. did you consider filing a (documentation) bug report? – ax. Oct 15 '09 at 19:18
  • 2
    Let's call it the ternary obfuscator. – GZipp Oct 15 '09 at 20:16
  • 1
    ax: Is `expr1 ?: expr3` really just syntactic sugar? If `expr1` is a function call, will it execute twice (meaning this is really syntactic sugar) or once (meaning the `?:` operator behaves differently without `expr2`)? – eyelidlessness Oct 15 '09 at 21:12
  • eyelidlessness: it will probably only execute once (see http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/Zend/zend_language_parser.y?revision=277815&view=markup#l634 and http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/Zend/zend_compile.c?revision=288096&view=markup#l4733 ). so ok, it is not syntactic sugar but indeed a binary op then. my point actually was to make some point against calling a useful language addition "full circle stupidity" and "ignorance" (and using bold upper case), regardless of some documentation flaws. – ax. Oct 16 '09 at 06:51
  • I think chaos' response may be hyperbolic, but its point isn't wrong. Ultimately, the problem isn't just the documentation, but the overloading of the behavior of the conditional operator to produce unexpected behavior. If you are familiar with the operator as ternary, then you will be surprised by its behavior **regardless** of whether it executes `expr1` once or twice. That is **absolutely** a stupid language change. It **never** helps programmers write clear code when you introduce an operator that behaves unexpectedly. – eyelidlessness Oct 16 '09 at 17:40
  • I only think it's a little bit stupid to overload `?:` so that it does what `||` does in better languages, as opposed to making `||` and `&&` behave properly in the first place. What's stupid is calling `?:` "the ternary operator", and what's really stupid is then making a situation where someone could speak, in some sense correctly, of "using the ternary operator in its binary form". – chaos Oct 17 '09 at 14:03
4

You should be setting a variable with the results of your database call before using the conditional operator for this purpose. Your example makes the database call twice.

For example:

$output = $this->db->get_where('my_db',array('id'=>$id))->row()->some_value);
$output = $output ? $output : "Some Value Not Set";
echo $output;

And with that established, this is a good case where it's really wiser to not use the conditional operator, which really isn't meant to be used as a general purpose if-then shortcut.

chaos
  • 122,029
  • 33
  • 303
  • 309
eyelidlessness
  • 62,413
  • 11
  • 90
  • 94
  • you could save one line by doing the first assignment inside the test: http://stackoverflow.com/questions/1574273/conditional-operator-shortcut-in-php/1574294#1574294 – ax. Oct 15 '09 at 18:59
4

if you need to reuse the long expression from the test after the ?, you can assign it to a variable inside the test (because assignments are expressions returning the assigned value) and use this variable after the ?:

$output = ($some_value = $this->db->get_where('my_db', array('id' => $id))->row()->some_value))
  ? $some_value 
  : "Some Value Not Set";
echo $output;
ax.
  • 58,560
  • 8
  • 81
  • 72
  • 5
    +1 for correct solution, but generally this code is less clear and concise than simply declaring the variable before the ternary operator. Saving an extra line of code is decreasing readability. – Corey Ballou Oct 15 '09 at 19:29
  • it might be less clear, but i don't think it is less concise :) – ax. Oct 15 '09 at 19:36
4

You seem to be afraid of whitespace. Use it! Liberally! Your code is much eaiser to read if you add a space before and after the question mark and the colon, respectively. If your statements get too long, add a newline. Try it, it won't hurt you.

innaM
  • 47,505
  • 4
  • 67
  • 87
3

I do believe that the conditional operator is the shortcut :) For the sake of saving function calls and readability, I suggest saving the value to a variable first.

$some_value = $this->db->get_where('my_db',array('id'=>$id))->row()->some_value);
$output = $some_value ? $some_value : "Some Value Not Set";
echo $output;
chaos
  • 122,029
  • 33
  • 303
  • 309
Paulo
  • 4,275
  • 2
  • 20
  • 20
1

Best way is to:

$output = $this->db->get_where('my_db',array('id'=>$id))->row()->some_value)
echo $output =($output)?$output:"Some Value Not Set";

Only executes once then!

Lizard
  • 43,732
  • 39
  • 106
  • 167