-1

I have a string coming from db like session_user_id denoting that I should grab the user_id from the session variable in PHP. This should ideally translate to $_SESSION['user']['id'] where the value exists. The following doesn't seem to work.

echo fillDefaultValues("session_user_id");

function fillDefaultValues($val)
{
    $expval = explode("_", $val);
    $j = "";
    if ($expval[0] == 'session') {
        for ($i=1; $i < count($expval); $i++) {
            $j .= "[".$expval[$i]."]";
        }
        $sessVal = $_SESSION[$j];
    }
    return $sessVal;
};

I have tried the variations like $sessVal = $_SESSION.$j, $sessVal = ${$_SESSION.$j}, $sessVal = $_SESSION[$j] but none seems to work.

6
  • Your code is looking for $_SESSION['[user][id]'] which doesn't exist. Commented Jan 23, 2021 at 18:08
  • Start with $sessVal = $_SESSION, then $sessVal = $sessVal[$expval[$i]]; and repeat. Commented Jan 23, 2021 at 18:09
  • stackoverflow.com/questions/33264853/… Commented Jan 23, 2021 at 18:10
  • Do what $_SESSION['user']['id'] does, don't try to generate PHP code. Read about accessing array items using the square bracket syntax. Commented Jan 23, 2021 at 18:24
  • @axiac My problem is how do I build that when I don't know the number levels? Commented Jan 25, 2021 at 15:33

1 Answer 1

0

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. I'll try this. My reference pattern is consistent, only that I don't know the number of levels or the array names (after session_).
With this solution, you can traverse to any number of levels/depths depending on the "array path" given in your string. If your string is users_ravi_details_birthday_year, it will yield the value of $arr['users']['ravi']['details']['birthday']['year'].

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.