30

In PHP I find myself writing code like this frequently:

$a = isset($the->very->long->variable[$index])
            ? $the->very->long->variable[$index]
            : null;

Is there a simpler way to do this? Preferably one that doesn't require me to write $the->very->long->variable[$index] twice.

hakre
  • 193,403
  • 52
  • 435
  • 836
oz1cz
  • 5,504
  • 6
  • 38
  • 58
  • By working OOP and use the __get and __set? – Ron van der Heijden Nov 29 '12 at 13:03
  • @DaHaKa: That might issue a warning on a server with good settings (`E_STRICT | E_ALL)` – Elias Van Ootegem Nov 29 '12 at 13:07
  • You could use a reference if you're using the same long variable often: `$ref = $the->very->long->variable; $a = !empty($ref[$index]) ? $ref[$index] : null; $b = !empty($ref[++$index])...`, or as @Bondye pointed out, use the magic getter method, and set it to return _either_ null or the property value – Elias Van Ootegem Nov 29 '12 at 13:09
  • Looks like that `->variable` could implement/wrapped into [`ArrayAccess`](http://php.net/ArrayAccess) and give back NULL per default for an unset index in an [`offsetGet`](http://php.net/arrayaccess.offsetget) operation. - Also please double-check for potential duplicates, you could find some gems on this site. – hakre Nov 29 '12 at 16:05
  • The maybe monad might work for this, although I don't understand it well enough to say for certain: https://github.com/ircmaxell/monad-php – user151841 Aug 26 '15 at 14:42

5 Answers5

57

An update, because PHP 7 is now out and is a game-changer on this point ; the previous answers are about PHP 5.

PHP 7 solves this issue. Because you are true at saying that it is frequent to write this in PHP, and that's absolutely not elegant.

In PHP 7 comes the Null Coalesce Operator (RFC), which is a perfect shorthand for the isset ternary condition.

Its goal is to replace this type of condition:

$var = isset($dict['optional']) ? $dict['optional'] : 'fallback';

By that:

$var = $dict['optional'] ?? 'fallback';

Even better, the null coalesce operators are chainable:

$x = null;
# $y = null; (undefined)
$z = 'fallback';

# PHP 7
echo $x ?? $y ?? $z   #=> "fallback"

# PHP 5
echo isset($x) ? $x : (isset($y) ? $y : $z)

The null coalesce operator acts exactly like isset() : the subject variable's value is taken if:

  • The variable is defined (it exists)
  • The variable is not null

Just a note for PHP beginners: if you use the ternary condition but you know that the subject variable is necessarily defined (but you want a fallback for falsy values), there's the Elvis operator:

$var = $dict['optional'] ?: 'fallback';

With the Elvis operator, if $dict['optional'] is an invalid offset or $dict is undefined, you'll get a E_NOTICE warning (PHP 5 & 7). That's why, in PHP 5, people are using the hideous isset a ? a : b form when they're not sure about the input.

Community
  • 1
  • 1
Morgan Touverey Quilling
  • 4,181
  • 4
  • 29
  • 41
10

Sadly no, because the RFC has been declined. And because isset is not a function but a language construct you cannot write your own function for this case.

Note: Because this is a language construct and not a function, it cannot be called using variable functions.

eisberg
  • 3,731
  • 2
  • 27
  • 38
2

If you only assign null instead of the non set variable, you can use:

$a = @$the->very->long->variable[$index];

@ makes that instruction throw no errors

Job Wong
  • 23
  • 1
  • 3
1

Assuming you know that $the->very->long->variable is set, and you're just worried about the array index....

$x = $the->very->long->variable;
$a = isset($x[$index]) ? $x[$index] : null;

Or for a more generic variant that you can use around you code:

function array_valifset($arr,$k, $default=null) {
    return isset($arr[$k]) ? $arr[$k] : $default;
}

then call it like this for any array value:

$a = array_valifset($the->very->long->variable,$index);
SDC
  • 14,192
  • 2
  • 35
  • 48
  • Thank you. I was hoping that I had merely overlooked a built-in feature. Apparently that is not the case. – oz1cz Nov 29 '12 at 13:11
  • nope. as @eisberg says, the PHP devs have explicitly rejected a shorthand isset solution. :-( I'm sure they have their reasons. – SDC Nov 29 '12 at 13:13
-1

I stumbled across the same problem and discovered that referencing an array element does not issue a notice or warning but returns null (at least PHP 5.6).

$foo = ['bar' => 1];

var_dump($bar = &$foo['bar']); // int 1
var_dump($baz = &$foo['baz']); // null

Inside an if statement:

if($bar = &$foo['bar']) {
    echo $bar;
}
if($baz = &$foo['baz']) {
    echo $baz;
}