vava
vava

Reputation: 25371

PHP and ?? operator

Like some people know, C# has very useful ?? operator which evaluates and returns expression on the right if expression on the left is null. It's very useful for providing default values, for example:

int spaces = readSetting("spaces") ?? 5;

If readSetting couldn't find "spaces" and returns null, variable spaces would hold default value of 5.

You could do almost the same in JavaScript and Ruby with || operator, as in

var spaces = readSetting("spaces") || 5;

although you couldn't have 0 as value of spaces in JavaScript in this case and false in both Ruby and JavaScript.

PHP has or operator and although it doesn't work as || in a sense that it doesn't return expression from the right, it still could be useful here:

$spaces = readSetting('spaces') or $spaces = 5;

with the note that "" and "0" are also treated like false in PHP in addition to false, 0 and null in most languages.

The question is, should I use the construction from above? Does it have side effects apart from treating large class of characters as false? And is there better construction that is usually used and recommended by PHP community this task?

Upvotes: 5

Views: 720

Answers (5)

Kickstart
Kickstart

Reputation: 21513

PHP 7 now supports ?? as the Null coalescing operator

The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). It returns its first operand if it exists and is not NULL; otherwise it returns its second operand.

<?php 
// Fetches the value of $_GET['user'] and returns 'nobody' 
// if it does not exist. 
$username = $_GET['user'] ?? 'nobody'; 
// This is equivalent to: 
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

// Coalescing can be chained: this will return the first 
// defined value out of $_GET['user'], $_POST['user'], and 
// 'nobody'. 
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody'; 
?>

http://php.net/manual/en/migration70.new-features.php

Upvotes: 5

Patrick Glandien
Patrick Glandien

Reputation: 7851

PHP 5.3.0 gives a shorter version of the ternary operator condition?true:false which goes as follows:

$spaces = readSettings('spaces') ?: 5;

Please notice that PHP 5.3.0 is still in beta and not yet production ready (its a release candidate already though), but it gives alot of new cool stuff like lambda functions and namespaces too, so it's definitely worth to check the features out!

Here is an article that describes the new features pretty well:

http://www.sitepoint.com/article/whats-new-php-5-3/

Upvotes: 6

Ferdinand Beyer
Ferdinand Beyer

Reputation: 67147

It is a good idea to be more explicit in cases like this, especially in PHP since it has somewhat confusing type conversion rules (e.g. "0" is false as you pointed out).

If you want to be strict, let your function readSettings return the correct setting or a well-defined value if no setting is found, e.g. null. Then you should use it as:

$spaces = readSettings('spaces');
if (null === $spaces) {
    $spaces = 5;
}

If you want to be more generous and only want $spaces to be non-empty, use:

$spaces = readSettings('spaces');
if (empty($spaces)) {    // or:  if (!$spaces) {
    $spaces = 5;
}

You could shorten it by the cost of a second function call or ugly constructs (not recommended):

$spaces = readSettings('space') ? readSettings('space') : 5;
$spaces = ($x = readSettings('space')) ? $x : 5;  // UGLY!

But watch out if you want 0 to be a valid value for $spaces!

From the Zen of Python:

Explicit is better than implicit.

In your case I would recommend to just add a second paramter $default to readSettings():

function readSettings($key, $default=null) {
    return isset($settings[$key]) ? $settings[$key] : $default;
}

$spaces = readSettings('spaces', 5); 

Upvotes: 6

altermativ
altermativ

Reputation: 690

How about this?

$spaces = ($tmp=readSettings('space')) ? $tmp : 5;

Or, more confusing but using only one variable:

$spaces = ($spaces=readSettings('space')) ? $spaces : 5;

Upvotes: 4

Parrots
Parrots

Reputation: 26882

If you want to guarantee that you get false or null, and not treat things like "0" as "false", you could do the following:

$spaces = readSetting('spaces');
if($spaces == null || $spaces === false) $spaces = 5;

The === operator in PHP looks for an identical match, so "0", "", won't equate to false. Obviously you might want to restyle the code to your liking, but you get the idea.

Upvotes: 1

Related Questions