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;
}
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
}
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
.
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);
}
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);
}
In PHP, operator @
suppresses warnings while evaluating an expression. For example, $array[$key]
returns the value with that key if it exists or null
if not, but it raises a warning if the key does not exist. Adding the @
operator to produce @$array[$key]
makes it equivalent to array_key_exists($key, $array) ? $array[$key] : null
. In fact, isset($something)
is only another way of saying @$something === null
.
So try this:
if (@$_POST['action'] === 'login')
{
// we're probably logging in, so let's process that here
}
My PHP projects use something similar to the snippet in the documentation of ErrorException
. This adds fail-fast semantics, where PHP $array[$key]
means throw an ErrorException
if it's not there and @$array[$key]
means use null
to mean not found (like an SQL LEFT JOIN
).
精彩评论