7

作为一名 Web 开发人员,我总是将这种方法用于登录表单或其他“保存”操作(忽略直接访问输入变量的危险):

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

为了使这不那么乏味并符合 DRY 原则(有点),我做了这个:

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
}

尽管我非常聪明地使用了动态变量名来访问超全局,但这还是失败了。

所以,我坚持使用这个丑陋的东西:

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
}

我的问题:有没有办法像我在第二个代码示例中尝试做的那样动态访问超全局变量?如果没有,是否有更好/更有效的方法来完成我在第三个代码示例中所做的事情?


我的解决方案:感谢Tom Haigh 的回答,这是我将使用的最终代码:

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

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

5 回答 5

3

你可以这样做:

function test($var) {
    //this 
    var_dump( $GLOBALS[$var] );

    //or this
    global $$var; //this is needed even for superglobals
    var_dump($$var);
}

test('_GET');

所以你可以在你的情况下使用这样的东西

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');

或者,您可以通过引用获取变量并使用isset(),例如

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
}
于 2010-08-24T16:12:27.420 回答
2

如果您只需要从一个来源获取,请使用 Tom's answer

但是,如果您对每个变量都这样做,即,如果您总是承认数据可以来自两个来源,那么最好的选择是合并它们。

您可以使用$_REQUEST,但我建议您不要使用它。它认为 POST 和 GET 数据的顺序是可php.ini配置的,它包括其他来源。

执行以下操作:

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

然后从$data.

于 2010-08-24T16:15:29.960 回答
1

怎么样: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);
}
于 2010-08-24T16:15:05.250 回答
-1

$_REQUEST默认包含 and 的内容时$_GET$_POST为什么需要 switch-case. 您可以直接使用它并消除$superglobal

function isset_and_is ($key, $value)
{
    return isset($_REQUEST[$key]) && ($_REQUEST[$key] == $value);
}
于 2010-08-24T16:13:28.750 回答
-1

在 PHP 中,运算符在计算@表达式时会抑制警告。例如,$array[$key]如果该键存在或不存在,则返回该值null,但如果该键不存在,则会引发警告。将@运算符添加到生产@$array[$key]使其等效于array_key_exists($key, $array) ? $array[$key] : null. 其实isset($something)只是另一种说法@$something === null

所以试试这个:

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

我的 PHP项目使用类似于. ErrorException这增加了快速失败的语义,其中 PHP意味着如果它不存在则$array[$key]抛出一个并且意味着使用意味着未找到(如 SQL )。ErrorException@$array[$key]nullLEFT JOIN

于 2015-01-22T16:05:16.157 回答