This concern is similar to accessing deeper levels of an array using dot or slash notation (x.y.z
, x/y/z
). One way to accomplish it is iterating through the path and returning the requested level when reached. Here's a simple non-recursive function that does the job:
function array_deep(array $array, string $key_path, string $separator = '/')
{
$path = explode($separator, $key_path);
$ref =& $array;
foreach($path as $node) {
if (isset($ref[$node])) {
$ref =& $ref[$node];
}
else {
// die('Undefined Index:' . $key_path); // or use your error-handling routine
return null;
}
}
return $ref;
}
What we do above is assign a reference to each progressive depth of the array, and then access the value of the next level, until the end of the path. If a given key doesn't exist, the function returns null
. You may want to implement your error/exception handler here to differentiate "index does not exist" from actual null
values. Usage as follows:
// sample array:
$array['x']['y']['z'] = 'yay';
// accessing the value:
$value = array_deep($array, 'x/y/z', '/');
echo $value; // yay
You can use any separator of your choice. For your case, you'd call:
$value = array_deep($_SESSION, 'user_id', '_');
Note that the "session_" prefix in the variable name coming from your database is noise here, since it doesn't form a part of the array structure (and since we're passing in $_SESSION
as the array), and should simply be trimmed out up front; e.g. as $path = substr($path, strlen('session_')
.
If you apply this in multiple cases, ensure that any variable names coming from your database actually match the pattern of data in your local variables, with each separator indicating a deeper array level. You can only automate this if the reference pattern is consistent.
Be aware that all separators will be exploded as path levels, and as such using separators that won't be a part of a PHP "word" is recommended. Since a single _
underscore is commonly used to represent a space, errors are likely when it's used as a separator. Think user/user_details/first_name
vs. user_user_details_first_name
: the first is clear, the second is ambiguous.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…