views:

57

answers:

4

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;
}
+2  A: 

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
}
Tom Haigh
A: 

When $_REQUEST by default contains the contents of $_GET and $_POST, why do you need switch-case. You can directly use this and eliminate $superglobal:

function isset_and_is ($key, $value)
{
    return isset($_REQUEST[$key]) && ($_REQUEST[$key] == $value);
}
shamittomar
`$_REQUEST` is unsafe if I only want to allow logins via `POST`, for example.
abrahamvegh
+1  A: 

How about: http://www.php.net/manual/en/function.filter-input.php

function isset_and_is ($superglobal, $key, $value) {
  switch($superglobal) {
    case 'post':
      $type = INPUT_POST;
      break;
    case 'get':
      $type = INPUT_GET;
      break;
  }
  $var = filter_input($type,$key);
  if(is_null($var)) return false;
  return($var == $value);
}
Mchl
Your answer completely ignores the question, and simply provides an equally crufty solution to my third code sample.
abrahamvegh
Honestly, I can't see how it's ignoring your question. Given you can actually use INPUT_* constants as an argument to this function to get rid of the switch, it cen become a really nice solution IMHO.
Mchl
+2  A: 

If you need to fetch from only one source, go with Tom's answer.

However, if you're doing this for every variable, i.e., if you always admit that data can come from two sources, the best alternative is to merge them.

You could use $_REQUEST, but I'd advise you against it. The order it considers POST and GET data is php.ini configurable, and it includes other sources.

Do something like:

$data = array_merge($_GET, $_POST); //POST has precedence

and then get your data from $data.

Artefacto
Doesn't GET have precedence here? I mean, if `$_POST['var']` and `$_GET['var']` are set, it will pick `$_GET['var']`
NullUserException
I'm not admitting data can always come from two sources; on the contrary, data will only ever come from one of the superglobals, depending on where I'm accessing it. But, I want to be able to re-use this function.
abrahamvegh
@Null Sorry, you're right. Fixed.
Artefacto