8

I am wondering why this doesn't work to assign a string to $separator:

$separator = $options['title-separator'] || ' | ';

Elsewhere, $option has been assigned to some text or an empty string. (Actually, in my real life case, it's some text, or FALSE, but either way…). $separator is TRUE instead of a string.

The following accomplishes what I want, but seems unnecessarily verbose:

$separator = ( $s = $options['title-separator'] ) ? $s : ' | ';

I come from JavaScript, where both these examples have the same result, which seems logical to me. What do I need to understand about PHP for this to make sense? Right now, I'm just annoyed by the hundreds of extra characters this will require for every place an option gets used.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Greg Perham
  • 1,835
  • 1
  • 17
  • 26
  • 1
    To avoid unnecessary notices use `$seperator = isset($options['title-seperator'] ? $options['title-separator'] : ' | ';`. However, don't see, where its too verbose. Its the most comprehensive way to say "If the key exists, use the corresponding value, else use X" – KingCrunch Jan 15 '12 at 20:22

7 Answers7

5

PHP 7 has introduced Null Coalescing operator in which you can use like

$first_name = $_POST['f_name'] ?? 'no data found';
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
5

See this on the PHP 5.3 coalesce function ?::

Coalesce function for PHP?

So you can write:

$separator = $options['title-separator'] ?: ' | ';

EDIT: As KingCrunch says, you will get this notice:

Notice: Undefined index: ...

, but only if you have configured your system so.

In our PHP codebase we have a custom function coalesce(...) defined, which returns the first alternative for which isset() returns true.

Community
  • 1
  • 1
The Nail
  • 8,355
  • 2
  • 35
  • 48
5

First

$seperator = isset($options['title-seperator'])
  ? $options['title-separator']
  : ' | ';

is not verbosive, it's just complete in what wants it tells you. However, with PHP5.3 you can use the shortcut

$seperator = $options['title-seperator'] ?: ' | ';

But you will get many notices about undefined index keys. I recommend to stay with the first example.

Another (in my eyes) cleaner solution is to introduce default values. Instead of using the options "as they are" merge them with an array of predefined values

$defaults = array(
  'title-separator' => ' | '
);
$options = array_merge ($defaults, $options);

Now you don't need to take care about it and you have all your defaults at one place, instead of scattered all over your code.

KingCrunch
  • 128,817
  • 21
  • 151
  • 173
  • 1
    Your mention of array_merge is the first time I've seen it. Yes, I will make use of that! …Got me thinking, Since PHP treats arrays and objects differently, is there a similar function for objects? I did a little poking, and I'd have to make a class and use extends, yes? (Maybe this is a new question). Cheers, thanks. – Greg Perham Jan 30 '12 at 16:32
3

I am wondering why this doesn't work to assign a string to $separator

Because the language is not defined that way....

The definition of the || operator says that $a || $b returns TRUE if either $a or $b is TRUE, not that it returns $a if $a evaluates to TRUE.

MZB
  • 2,071
  • 3
  • 21
  • 38
1

That can be done! Not exactly like in javascript as the languages work differently.

This is how you could do it, kind of like how you do it in javascript:

($separator = $options['title-separator'])
    || ($separator = ' | ');

The difference here is you are checking against the variable after doing the assignment. Because PHP will not continue and execute anything after || if the first part evaluates to TRUE, you end up only doing the first assignment.

This is a very neat and readable way to chain fallbacks in my opinion. You could chain more fallback assignments if you need to, which would be a lot more messier with normal if statements and same with the shorthand "? :"

Manne Busk
  • 11
  • 1
  • I'm pretty sure you read the [answer posted by @KingCrunch](https://stackoverflow.com/a/8873141/1369473) before you posted your answer... or did you?! – Fr0zenFyr Apr 07 '18 at 11:05
0

You can make the function.

if(!function_exists('gettrue')){
  function gettrue(){
    $args = func_get_args();
    foreach($args as $arg){
      if($arg) return $arg;
    }

    return $arg;
  }  
}

$test = gettrue(false, 0, '', 'yes');
var_dump($test);  // string(3) "yes"
Masamoto Miyata
  • 171
  • 4
  • 9
0
$separation = $var1 . ($var2 ? ($var1 ? ' | ' : '') . $var2 : $var2);
MaartenDev
  • 5,631
  • 5
  • 21
  • 33
adyoi
  • 87
  • 1
  • 14