3
\$\begingroup\$

I've just coded a little function to check and get a deep array value. Basically, I need to return the value or null if it's not set or does not exists, or in general not useful for databases records. I need to check things like $myarray[key1][key2][key3] etc..

function get_array_deep_value(array $array, array $fields){
 $value = $array;
 foreach($fields as $field){
 $v = $value[$field] ?? null;
 if(empty($v) && $v != 0){ // note: using != operator because it will convert '0' to 0 (while !== does not)
 $value = null; 
 break;
 } 
 $value = $v;
 }
 return $value;
}

Any possible improvements? :)

asked Dec 26, 2021 at 11:38
\$\endgroup\$
3
  • 1
    \$\begingroup\$ What if the deep value that you want is a zero, but your script returns null? If you are going to call empty() that should happen before null coalescing. \$\endgroup\$ Commented Dec 26, 2021 at 22:51
  • 1
    \$\begingroup\$ Your break seems like it is part of a protective measure. Would you prefer instead to throw an exception because the path to the desired element suffered a breakage? How do you differentiate between a truly found null and a fallback null? \$\endgroup\$ Commented Dec 26, 2021 at 22:58
  • \$\begingroup\$ @mickmackusa the break is there because if the value is not the one expected or is undefined/null/empty string, I want a null value. If $v == 0, it will return 0, not null. \$\endgroup\$ Commented Dec 28, 2021 at 8:20

1 Answer 1

3
\$\begingroup\$

I recommend avoiding declaring single-use variables. I also recommend throwing an exception when a broken path is passed into your function. Better variable naming will help others to instantly understand your code.

Code: (Demo)

function get_array_deep_value(array $array, array $levelKeys) {
 foreach ($levelKeys as $index => $key) {
 if (!key_exists($key, $array)) {
 throw new Exception("key $key not found at level index $index");
 }
 $array = $array[$key];
 }
 return $array;
}
$myArray = [
 'one' => [
 'two' => [
 'three' => [
 4
 ]
 ]
 ]
];
$pathArrays = [
 ['one', 'two', 'three'],
 ['one', 'two'],
 ['one'],
 ['two']
];
foreach ($pathArrays as $pathArray) {
 try {
 var_export(get_array_deep_value($myArray, $pathArray));
 } catch (Exception $e) {
 echo $e->getMessage();
 }
 echo "\n---\n";
}
answered Dec 27, 2021 at 0:30
\$\endgroup\$
8
  • \$\begingroup\$ Hey, key_esists... Wow... Elegant... :) Thank you! But will the exception also break the loop? \$\endgroup\$ Commented Dec 28, 2021 at 8:22
  • \$\begingroup\$ No, it is caught. Add another valid path to test this. \$\endgroup\$ Commented Dec 28, 2021 at 8:22
  • \$\begingroup\$ ' Add another valid path to test this': what do you mean? Anyway, I need always null when the value is not found/valid, since that value will be written on a database field. \$\endgroup\$ Commented Dec 28, 2021 at 8:28
  • 1
    \$\begingroup\$ You can assign the fallback variable in the catch body 3v4l.org/rvhX9 or just return null without throwing an exception, but it will be a more professional approach to differentiate truly extracted values from fallback values. \$\endgroup\$ Commented Dec 28, 2021 at 8:38
  • 1
    \$\begingroup\$ Fair enough, then that logical requirement should be expressed in your question and in your project's code. \$\endgroup\$ Commented Dec 28, 2021 at 13:36

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.