Skip to content
Advertisement

PHP session variable name as string

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.

Advertisement

Answer

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.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement