Search code examples
phpsuperglobals

Is there any way to dynamically access a superglobal?


As a web developer, I'm always using this approach to something like a login form or other “save” operation (ignoring the dangers of directly accessing input variables):

if (isset($_POST['action']) && $_POST['action'] == 'login')
{
    // we're probably logging in, so let's process that here
}

To make this less tedious and keeping in line with DRY principles (sort of), I cooked this up:

function isset_and_is ($superglobal, $key, $value)
{
    $ref = '_' . strtoupper($superglobal);

    return isset($$ref[$key]) && $$ref[$key] == $value;
}

if (isset_and_is('post', 'action', 'login'))
{
    // we're probably logging in, so let's process that here
}

This fails miserably, despite my oh-so-clever use of dynamic variable names to access the superglobal.

So, I'm stuck using this ugly:

function isset_and_is ($superglobal, $key, $value)
{
    switch (strtoupper($superglobal))
    {
        case 'GET':     $ref =& $_GET;     break;
        case 'POST':    $ref =& $_POST;    break;
        case 'REQUEST': $ref =& $_REQUEST; break;
        default:        die('megafail');   return;
    }

    return isset($ref[$key]) && $ref[$key] == $value;
}

if (isset_and_is('post', 'action', 'login'))
{
    // we're probably logging in, so let's process that here
}

My question: Is there a way to dynamically access the superglobal variables like I'm attempting to do in my second code sample? If no, is there a better/more efficient way to accomplish what I'm doing in the third code sample?


My solution: Thanks to Tom Haigh's answer, here's the final code I'll be going with:

function isset_and_is ($superglobal, $key, $value)
{
    $ref =& $GLOBALS['_' . strtoupper($superglobal)];

    return isset($ref[$key]) && $ref[$key] == $value;
}

Solution

  • You can do it like this:

    function test($var) {
        //this 
        var_dump( $GLOBALS[$var] );
    
        //or this
        global $$var; //this is needed even for superglobals
        var_dump($$var);
    }
    
    test('_GET');
    

    so you could use something like this in your case

    function isset_and_is ($superglobal, $key, $value) {
        $var = '_' . $superglobal;
        return isset($GLOBALS[$var]) && ($GLOBALS[$var][$key] == $value);
    }
    
    $is_login = isset_and_is('GET', 'action', 'login');
    

    Or alternatively you can take the variable by reference and use isset(), e.g.

    function get_var(& $var) {
        if (isset($var)) {
            return $var;
        }
        return null;
    }
    
    //will not give you a notice if not set
    $post_var = get_var($_POST['var']);
    
    if (get_var($_GET['action']) == 'login') {
        //stuff
    }