3

If I have this array,

ini_set('display_errors', true);
error_reporting(E_ALL);

$arr = array(
  'id' => 1234,
  'name' => 'Jack',
  'email' => '[email protected]',
  'city' => array(
    'id' => 55,
    'name' => 'Los Angeles',
    'country' => array(
      'id' => 77,
      'name' => 'USA',
     ),
  ),
);

I can get the country name with

$name = $arr['city']['country']['name'];

But if the country array doesn't exist, PHP will generate warning:

Notice: Undefined index ... on line xxx

Sure I can do the test first:

if (isset($arr['city']['country']['name'])) {
  $name = $arr['city']['country']['name'];
} else {
  $name = '';  // or set to default value;
}

But that is inefficient. What is the best way to get $arr['city']['country']['name'] without generating PHP Notice if it doesn't exist?

3
  • Why is it "inefficient"? Commented May 28, 2012 at 8:28
  • Where does the data come from? If from a third party, you should write one parse function to parse this into a standardized data structure of which you know which keys exist and which don't... Commented May 28, 2012 at 8:32
  • 1
    @deceze: It is inefficient since getting a single value takes 4+ lines. Commented May 28, 2012 at 8:33

2 Answers 2

5

I borrowed the code below from Kohana. It will return the element of multidimensional array or NULL (or any default value chosen) if the key doesn't exist.

function _arr($arr, $path, $default = NULL) 
{
  if (!is_array($arr))
    return $default;

  $cursor = $arr;
  $keys = explode('.', $path);

  foreach ($keys as $key) {
    if (isset($cursor[$key])) {
      $cursor = $cursor[$key];
    } else {
      return $default;
    }
  }

  return $cursor;
}

Given the input array above, access its elements with:

echo _arr($arr, 'id');                    // 1234
echo _arr($arr, 'city.country.name');     // USA
echo _arr($arr, 'city.name');             // Los Angeles
echo _arr($arr, 'city.zip', 'not set');   // not set
Sign up to request clarification or add additional context in comments.

Comments

3

The @ error control operator suppresses any errors generated by an expression, including invalid array keys.

$name = @$arr['city']['country']['name'];

2 Comments

Actually I want to write clean code, so I avoid @ to catch any warnings and notices and fix them.
If you wanted to write clean code, then you would use isset() as you explain in your very question. But it's verbose, which is why you're looking for alternatives. @ is the least verbose of them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.