Ternary operator shorthand to use subject of expression in true/false clause rather than repeating

StackOverflow https://stackoverflow.com/questions/19978055

Question

Say I have a long(ish) variable, $row['data']['manybullets']['bullets']['bullet'][0], and want to test whether it's set using the ternary operator:

$bulletx = 
    isset($row['data']['property']['bullets']['bullet'][0])    // condition
    ? $row['data']['property']['bullets']['bullet'][0]         // true
    : 'empty';                                                 // false

Is there anyway for me to reference the subject of the expression rather than repeating it. E.g.

$bulletx = 
    isset($row['data']['property']['bullets']['bullet'][0])    // condition
    ? SUBJECT                                                  // true
    : 'empty';                                                 // false    

Curious.

Was it helpful?

Solution

PHP supports foo ?: bar but unfortunately this won't work because of the isset() in your condition.

So unfortunately there is no really good way to do this in a shorter way. Besides using another language of course (e.g. foo.get(..., 'empty') in python)

However, if the default value being evaluated in any case is not a problem (e.g. because it's just a static value anyway) you can use a function:

function ifsetor(&$value, $default) {
    return isset($value) ? $value : $default;
}

Because of the reference argument this will not throw an E_NOTICE in case of an undefined value.

OTHER TIPS

You can do it like this:

$bulletx = ($r=$row['data']['property']['bullets']['bullet'][0]) ? $r : 'empty';

See working demo

Not really, without triggering an E_NOTICE warning, but if you decide to ignore those you could achieve it like this.

$bulletx = 
    $row['data']['property']['bullets']['bullet'][0]    // true
    ?: 'empty';                                          // false    

No built-in way, but you can write a wrapper for isset that checks the array keys.

function array_isset(&$array /* ... */) {
    $a = $array;
    if (! is_array($a)) {
        return false;
    }
    for ($i = 1; $i < func_num_args(); $i++) {
        $k = func_get_arg($i);
        if (isset($a[$k])) {
            $a = $a[$k];
        } else {
            return false;
        }
    }

    return $a;
}

$bulletx = array_isset($row, 'data', 'property', 'bullets', 'bullet', 0) ?: 'empty';

I like this way, as it keeps the same API as isset() and can make use of the ?: short cut.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top