2010-08-24 13 views
6

Come sviluppatore web, sto utilizzando sempre questo approccio per qualcosa di simile a un modulo di accesso o di altri “Salva” operazione (ignorando i pericoli di variabili di input che accedono direttamente):C'è un modo per accedere dinamicamente ad un superglobale?

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

per rendere questo meno noioso e in linea con i principi secco (o quasi), ho cucinato questo in su:

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 
} 

questo fallisce miseramente, nonostante il mio uso oh-così-intelligente di nomi di variabili dinamiche per accedere al superglobale.

Così, mi sono bloccato con questo brutto:

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 
} 

La mia domanda: Esiste un modo per accedere in modo dinamico le variabili superglobali come sto tentando di fare nel mio secondo esempio di codice? Se no, c'è un modo migliore/più efficace per realizzare ciò che sto facendo nel terzo codice di esempio?


La mia soluzione: Grazie a Tom Haigh's answer, ecco il codice finale io vado con:

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

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

E cosa c'è che non va nel primo campione? – NullUserException

+0

NullUserException: DRY :) –

+1

IMO il primo campione è più chiaro, DRYer e facile per chiunque conosca PHP. Mentre gli altri ... – NullUserException

risposta

3

Si può fare in questo modo:

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

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

test('_GET'); 

in modo da potrebbe usare qualcosa del genere nel tuo 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'); 

In alternativa, è possibile prendere la variabile per riferimento e utilizzare isset(), ad es.

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

Quando $_REQUEST per default contiene il contenuto della $_GET e $_POST, perché avete bisogno di passare per caso. È possibile utilizzare direttamente questo ed eliminare $superglobal:

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

'$ _REQUEST' non è sicuro se voglio consentire solo gli accessi tramite' POST', ad esempio. –

1

ne dite: 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

La risposta ignora completamente la domanda e fornisce semplicemente una soluzione altrettanto cruenta al mio terzo esempio di codice. –

+1

Onestamente, non riesco a capire come stia ignorando la tua domanda. Dato che puoi effettivamente usare le costanti INPUT_ * come argomento per questa funzione per liberarti dello switch, diventa una soluzione davvero bella. – Mchl

2

Se avete bisogno di recuperare da una sola fonte, andare con Tom answer.

Tuttavia, se lo fai per ogni variabile, ad esempio, se ammetti sempre che i dati possono provenire da due fonti, l'alternativa migliore è unirle.

Potresti usare $_REQUEST, ma ti consiglio di non farlo. L'ordine che considera i dati POST e GET è php.ini configurabile e include altre fonti.

fare qualcosa di simile:

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

e quindi ottenere i dati da $data.

+0

Non esiste qui la precedenza? Voglio dire, se '$ _POST ['var']' e '$ _GET ['var']' sono impostati, selezionerà '$ _GET ['var']' – NullUserException

+0

Non sto ammettendo che i dati possano sempre venire da due fonti; al contrario, i dati verranno sempre e solo da uno dei superglobali, a seconda di dove sto accedendo. Ma, voglio essere in grado di riutilizzare questa funzione. –

+0

@Null Ci dispiace, hai ragione. Fisso. – Artefacto

0

In PHP, l'operatore @ sopprime gli avvisi durante la valutazione di un'espressione. Ad esempio, $array[$key] restituisce il valore con quella chiave se esiste o null in caso contrario, ma genera un avviso se la chiave non esiste. L'aggiunta dell'operatore @ alla produzione di @$array[$key] equivale a array_key_exists($key, $array) ? $array[$key] : null. Infatti, isset($something) è solo un altro modo di dire @$something === null.

Quindi provare questo:

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

miei progetti PHP usano qualcosa di simile al frammento in documentation of ErrorException. Questo aggiunge semantica a prova di errore, dove PHP $array[$key] significa lanciare un ErrorException se non è lì e @$array[$key] significa usare null significa non trovato (come un SQL LEFT JOIN).

Problemi correlati