4
\$\begingroup\$

I currently use this code pattern fairly frequently

if(array_key_exists('possible_key', $array)) {
    $my_variable = $array['possible_key'];
} else {
    $my_variable = 'my default value';
}

Is there a better way to be writing this?

\$\endgroup\$
4
\$\begingroup\$

One quick change you can do is making use of ternary operator instead of writing if else block.

$my_variable = array_key_exists('possible_key', $array) 
               ? $array['possible_key'] 
               : 'my default value';
| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ Never thought of using multiple lines with the ternary operator before, though I can see how this would be a very long line otherwise (and it does seem more readable like this). Is it considered a best practice to do this? \$\endgroup\$ – Ben Zittlau Oct 30 '12 at 17:33
  • \$\begingroup\$ Side note: What's the difference between array_key_exists('possible_key', $array) and isset($array['possible_key'])? \$\endgroup\$ – Joseph Silber Oct 31 '12 at 1:44
  • 2
    \$\begingroup\$ @JosephSilber $array['possible_key'] = null; isset($array['possible_key']); /* false */ array_key_exists('possible_key', $array); /* true */ \$\endgroup\$ – Corbin Oct 31 '12 at 3:01
3
\$\begingroup\$

I would prefer to keep it simple and not to use if else. Just assign it the default value, and change only when the condition meets.

$my_variable = 'my default value';
if(array_key_exists('possible_key', $array)) $my_variable = $array['possible_key'];
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$
class ArrayHelper {

    public static function KeyExists($source, $key) {
        return isset($source[$key]) || array_key_exists($key, $source);
    }

    public static function GetValueOrDefault($source, $key, $default) {
        return self::KeyExists($source, $key) ? $source[$key] : $default;
    }

}

This is from my library it's similar to the other solutions but it's using a little hack: the array_key_exists() is a slow function so i execute first an isset() 'function' and if it's says "yes, it exists" then i don't have to execute the array_key_exists() function. The reason why isset() is not enough is the isset() will return FALSE if the key exists but the value is NULL.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ That's rather expensive don't you think? Calling up to 4 functions (ArrayHelper::GetValueOrDefault(), ArrayHelper::KeyExists(), isset(), array_key_exists) rather than a ternary calling 1 function (array_key_exists). \$\endgroup\$ – jsanc623 Oct 30 '12 at 23:09
  • \$\begingroup\$ The isset in KeyExists is redundant. isset being true is sufficient for array_key_exists to be true. (Not the inverse though -- your method could consist of only the array_key_exists call and have the same functionality. If it consisted of only the isset call, it would not have the same functionality.) Basically your function now is (a and b) or a (where a = does the key exist and b = the value is not null). \$\endgroup\$ – Corbin Oct 31 '12 at 3:11
  • \$\begingroup\$ Hrmm, apparently managed to not read your paragraph explaining why you used isset and array_key_exists earlier. I suppose my previous comment should be ignored. I do think you're way over thinking performance though. If an array_key_exists call is even close to being a bottleneck of an application, something is seriously wrong. \$\endgroup\$ – Corbin Oct 31 '12 at 4:54
  • 1
    \$\begingroup\$ @jsanc623: no it's not. Using your solution will request more memory for the PHP becouse of the ternary operator. When checking something with ternary operator in an array (isset() or anything else) the PHP will copy the full array before executing the checking. \$\endgroup\$ – Peter Kiss Oct 31 '12 at 7:08
  • \$\begingroup\$ @PeterKiss, Actually if the key exists, your method of using isset before array_key_exists will be slower. \$\endgroup\$ – Pacerier Mar 8 '15 at 15:02
1
\$\begingroup\$

Is there an atomic way to check if the value exists by a key AND return the value, so there will be just one query to the array? I think that this was the original idea of the author of the question. In a very large array, all examples here have shown essentially too lookup: for example array_key_exists('possible_key', $array) ? $array['possible_key'] etc...

A better way would be a single operation with the array that would not give a PHP run time warning in the key does not exist.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This re-statement of the question is what I was originally looking for, and what brought me here. It seems a single lookup isn't possible in PHP, but Hack has a built-in idx() with this behavior. docs.hhvm.com/hack/reference/function/HH.idx \$\endgroup\$ – AaronDanielson Mar 26 '18 at 17:12
-1
\$\begingroup\$

Untested code here as I don't have access to my dev machine, but taking Sky's ternary suggestion above and simplifying it (one empty() call is faster than an array_key_exists (see https://stackoverflow.com/questions/6884609/array-key-existskey-array-vs-emptyarraykey)

$var = empty($array['possible_key']) ? 'default value' : $array['possible_key']; 
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ If $array['possible_key'] is set to '' or 0, this'll return 'default value'. \$\endgroup\$ – Joseph Silber Oct 31 '12 at 1:45
  • 1
    \$\begingroup\$ "one empty() call is faster than an array_key_exists" Correct functionality is a lot more important than performance (in this context, though also usually in general). But yes, if he's willing to ignore values containing 0, empty, '0', etc, this is shorter and a tiny bit faster. (isset would probably be a better fit here than empty by the way. isset has fewer false negatives in this context.) \$\endgroup\$ – Corbin Oct 31 '12 at 3:05
  • \$\begingroup\$ Ah...true guys....woops \$\endgroup\$ – jsanc623 Oct 31 '12 at 3:49
-3
\$\begingroup\$

I prefer to use use isset and make little refactor and wrap that code to function/method

function defaultize( $array_var ,$defaul_val ){
 if(isset($array_var)) {
    $ret = $array_var;
 } else {
    $ret = 'my default value';
 }
 return $ret;
}

and then use in code

$my_variable = defaultize($array['possible_key'],'my default_value' );
$my_variable2 = defaultize($array['possible_key2'],'my default_value2' );
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ defaultize($array['possible_key'],'my default_value' ); <-- if 'possible_key' dows not exists the PHP will throw an E_NOTICE warning and your function body is messed up. \$\endgroup\$ – Peter Kiss Oct 30 '12 at 18:52
  • \$\begingroup\$ $array seem uninitialized inside the function. \$\endgroup\$ – palacsint Oct 30 '12 at 18:52
  • \$\begingroup\$ Ups, sorry just fixed that \$\endgroup\$ – Lacoz Oct 30 '12 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.