Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an idiomatic way to get a potentially undefined key from an array in PHP?

Tags:

arrays

idioms

php

PHPeoples, I'm so tired of doing this

$value = isset($arr[$key]) ? $arr[$key] : null;

Or this

$value = array_key_exists($key, $arr) ? $arr[$key] : null;

Don't nobody tell me to do

$arr   = array(1);
$key   = 5;
$value = $arr[$key];
// Notice: Undefined offset: 5

I got bronchitis. Ain't nobody got time f'dat.


I could make a function, I guess...

function array_get(Array $arr, $key, $default=null) {
  return array_key_exists($key, $arr)
    ? $arr[$key]
    : $default
  ;
}

But is this the best (most idiomatic) way?

like image 355
Mulan Avatar asked May 06 '14 18:05

Mulan


3 Answers

More elegant way of doing it:

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

Now you can just do:

$value   = ifsetor($arr[$key]);
$message = ifsetor($_POST['message'], 'No message posted');

etc. Here $value is passed by reference, so it wouldn't throw a Notice.

Further reading:

  • NikiC's blog — The case against the ifsetor function
  • PHP RFC — https://wiki.php.net/rfc/ifsetor
like image 198
Amal Murali Avatar answered Nov 15 '22 10:11

Amal Murali


If you need to make sure certain keys exist then you can create a default array and merge in your input (or whatever). That way all necessary keys will exist and they will be updated if possible:

$defaults = array(
    'foo' => '',
    'bar' => ''
);

$data = array_merge($defaults, $someOtherArray);

Docs for array_merge(): http://php.net/array_merge

I find this helpful when taking into consideration check-boxes on a HTML form that may or may not show up in $_GET or $_POST.

Note that this process expects string array keys, not numeric ones. See the documentation for clarification.

like image 32
Jasper Avatar answered Nov 15 '22 09:11

Jasper


Don't forget the function isset() does not return TRUE for array keys that correspond to a NULL value, while array_key_exists() does. So all above answer don't correct work with NULL element in array. You can check my edit answer for this situation. For example we had some array:

   $test = array(NULL,'',0,false,'0');

If we use (from answer above in this topic) function:

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

and try to get array data:

echo '---------------------';
var_dump($test);
echo 'Array count : '.count($test).'<br>';
echo '---------------------';
var_dump(ifsetor($test[0], 'Key not exists'));
var_dump(ifsetor($test[1],'Key not exists'));
var_dump(ifsetor($test[2],'Key not exists'));
var_dump(ifsetor($test[3], 'Key not exists'));
var_dump(ifsetor($test[4],'Key not exists'));
var_dump(ifsetor($test1[5],'Key not exists'));

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

our result be:

---------------------

array (size=5)
  0 => null
  1 => string '' (length=0)
  2 => int 0
  3 => boolean false
  4 => string '0' (length=1)

Array count : 5
---------------------

string 'Key not exists' (length=9) //But value in this key of array - NULL! and key exists

string '' (length=0)

int 0

boolean false

string '0' (length=1)

string 'Key not exists' (length=9)

So we can check it use isset and array_key_exists together. Don't forget check this is array or not;

echo '---------------------';
var_dump($test);
echo 'Array count : '.count($test).'<br>';
echo '---------------------';
var_dump(array_get($test, 0, 'Key not exists'));
var_dump(array_get($test, 1,'Key not exists'));
var_dump(array_get($test, 2,'Key not exists'));
var_dump(array_get($test, 3, 'Key not exists'));
var_dump(array_get($test, 4,'Key not exists'));
var_dump(array_get($test, 5,'Key not exists')); //Key not exists
var_dump(array_get($test1, 5,'Key not exists')); //This is not array


function array_get($arr, $key, $default=null) {
  if(is_array($arr)){
    return  isset($arr[$key]) || array_key_exists($key, $arr)
        ? $arr[$key]
        : $default;
  }else{
    return 'No array given';
  }

}

Now the answer is correct:

---------------------

array (size=5)
  0 => null
  1 => string '' (length=0)
  2 => int 0
  3 => boolean false
  4 => string '0' (length=1)

Array count : 5
---------------------

null  //Perfect - key exists!

string '' (length=0)

int 0

boolean false

string '0' (length=1)

string 'No array given' (length=14)

string 'Key not exists' (length=14)
like image 22
Brotheryura Avatar answered Nov 15 '22 10:11

Brotheryura