2010-08-24 11 views
6

Como desarrollador web, siempre estoy usando este enfoque a algo así como un formulario de acceso o de otro tipo “salvar” la operación (ignorando los peligros de las variables de entrada con el acceso directo):¿Hay alguna forma de acceder dinámicamente a un superglobal?

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

para hacer que esto sea menos tedioso y manteniendo la coherencia con los principios seco (tipo de), cociné esto:

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 
} 

esta falla desgraciadamente, a pesar de mi uso oh-tan-inteligente de nombres de variables dinámicas para acceder a la superglobal.

Por lo tanto, estoy atascado utilizando esta fea:

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 
} 

Mi pregunta: ¿Existe una manera de acceder dinámicamente las variables superglobales que estoy tratando de hacer en mi segundo ejemplo de código? Si no, ¿hay una forma mejor/más eficiente de lograr lo que estoy haciendo en la tercera muestra de código?


Mi solución: Gracias a Tom Haigh's answer, aquí está el código final me voy con:

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

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

¿Y qué pasa con la primera muestra? – NullUserException

+0

NullUserException: DRY :) –

+1

IMO la primera muestra es más clara, más seca y fácil para cualquiera que conozca PHP. Mientras que los otros ... – NullUserException

Respuesta

3

Puede hacerlo de esta manera:

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

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

test('_GET'); 

por lo que podría usar algo como esto en su caso

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

O, como alternativa, puede tomar la variable por referencia y usar isset(), p. Ej.

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 
} 
-1

Cuando $_REQUEST por defecto contiene el contenido de $_GET y $_POST, ¿por qué necesita cambiar caso. Se puede utilizar directamente este y eliminar $superglobal:

function isset_and_is ($key, $value) 
{ 
    return isset($_REQUEST[$key]) && ($_REQUEST[$key] == $value); 
} 
+0

'$ _REQUEST' no es seguro si solo quiero permitir el inicio de sesión mediante' POST', por ejemplo. –

1

¿Qué tal: 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); 
} 
+0

Su respuesta ignora por completo la pregunta, y simplemente proporciona una solución igualmente ingeniosa para mi tercer ejemplo de código. –

+1

Honestamente, no puedo ver cómo está ignorando su pregunta. Dado que en realidad se pueden usar las constantes INPUT_ * como argumento de esta función para deshacerse del interruptor, se convierte en una muy buena solución en mi humilde opinión. – Mchl

2

Si tendrá que obtener de una sola fuente, ir con Tom de answer.

Sin embargo, si está haciendo esto para cada variable, es decir, si siempre admite que los datos pueden provenir de dos fuentes, la mejor alternativa es fusionarlas.

Puede usar $_REQUEST, pero le aconsejaría que no lo haga. El orden en que considera los datos POST y GET es php.ini configurable e incluye otras fuentes.

hacer algo como:

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

y luego obtener sus datos de $data.

+0

¿NO OBTIENE prioridad aquí? Quiero decir, si '$ _POST ['var']' y '$ _GET ['var']' están configurados, se elegirá '$ _GET ['var']' – NullUserException

+0

No estoy admitiendo que los datos siempre puedan provenir de dos fuentes; por el contrario, los datos solo llegarán de uno de los superglobales, según el lugar al que acceda. Pero, quiero poder volver a utilizar esta función. –

+0

@Null Lo sentimos, tienes razón. Fijo. – Artefacto

0

En PHP, el operador @ suprime las advertencias al evaluar una expresión. Por ejemplo, $array[$key] devuelve el valor con esa clave si existe o null si no, pero genera una advertencia si la clave no existe. Agregar el operador @ para producir @$array[$key] lo hace equivalente a array_key_exists($key, $array) ? $array[$key] : null. De hecho, isset($something) es solo otra forma de decir @$something === null.

Así que trate esto:

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

Mis proyectos PHP utilizan algo similar al fragmento en el documentation of ErrorException. Esto agrega semántica a prueba de fallas, donde PHP $array[$key] significa arrojar un ErrorException si no está allí y @$array[$key] significa usar null para significar no encontrado (como un SQL LEFT JOIN).

Cuestiones relacionadas