Modifica diretta di superglobali

19

Ho visto persone (che generalmente scrivono un buon codice) modificare direttamente l'array $_POST con un codice come questo:

// Add some value that wasn't actually posted
$_POST['last_activity'] = time();

// Alter an existing post value
$_POST['name'] = trim($_POST['name']);

// Our pretend function
// Pass the entire $_POST array as data to work with in the function
// The function update_record() will read only the values we actually need
update_record($_POST);

// ...That sure was easier than creating a new array 
//  with only the $_POST values we actually need.

È logico che update_record() non debba accedere direttamente a $ _POST, quindi possiamo passare ad altri array di dati, ad esempio, ma sicuramente questo è un design pigro, cattivo o forse solo sbagliato? Tuttavia, stiamo ancora passando un array valido a update_record() , quindi perché crearne uno nuovo?

Questo non è il punto della domanda, solo un esempio di utilizzo. Tuttavia, ho sentito molte persone dire che questo non dovrebbe essere fatto con $_REQUEST di dati, ed è una cattiva pratica. Ma perché? Sembra abbastanza innocuo.

Esempi:

  • Impostazione di un valore predefinito $_GET (o post) che in realtà non esiste

  • Aggiunta di valori di $_POST che non sono stati effettivamente pubblicati dopo l'invio di un modulo

  • Disinfettare o filtrare direttamente i valori dell'array $_GET o chiavi molto presto nello script (servizi igienici di riserva ... perché no?)

  • Impostazione manuale di un valore $_POST prima dell'invio del modulo per popolare un input con un valore predefinito (quando l'input legge $_POST per il valore predefinito; l'ho fatto)

  • Crea i tuoi valori di $_SERVER ? Certo, hey perché no?

  • E gli altri, come $_COOKIE e $_SESSION ? Ovviamente dobbiamo modificare quelli direttamente giusto? Allora perché non gli altri?

Dovrebbe modificare direttamente superglobali mai essere fatto, o è OK fare in alcune istanze?

    
posta Wesley Murch 13.05.2011 - 01:06
fonte

6 risposte

16

Dato che PHP sta già impostando questi superglobali, non penso che sia evil per modificarli. In alcuni casi, potrebbe essere il modo migliore per risolvere i problemi ... in particolare quando si tratta di codice di terze parti che non è possibile modificare facilmente. (Potrebbero utilizzare $_GET direttamente o assumere alcune chiavi in $_SERVER , ecc.)

Tuttavia, in generale, penso che sia una cattiva pratica quando si scrive il proprio codice. La modifica dei dati di $_REQUEST con alcuni filtri dietro le quinte eseguiti automaticamente su ogni pagina probabilmente introdurranno effetti collaterali. (Vedi tutti i problemi che le "virgolette" hanno causato per la prova.)

Quindi, se non hai intenzione di farlo (filtra automaticamente i superglobali), allora quanto segue non ti dà alcun vantaggio:

$_POST['foo'] = filter($_POST['foo']);

quando puoi fare semplicemente:

$foo = filter($_POST['foo']);

Penso che sia molto più chiaro fare la distinzione a livello di sito che $_POST e $_GET sono sempre dati non filtrati e non affidabili, e dovrebbero mai essere usato così com'è.

Copiando il valore filtrato su un'altra variabile, stai affermando che, "Capisco cosa sto facendo ... Ho filtrato questo input, ed è sicuro da usare."

    
risposta data 13.05.2011 - 19:24
fonte
9

In genere suggerisco di non modificare i super-globali predefiniti in modo che sia chiaro quali sono i dati disinfettati e quali sono i dati non elaborati / non attendibili.

Altri potrebbero suggerire che se pulisci i superglobali all'inizio del ciclo di richiesta, non devi preoccuparti di loro altrove.

Li abbinerò sempre quando ne hai bisogno con:

$id = (int)$_POST['id'];

o simile.

In termini di altre variabili è buona norma non scrivere su nessuno di $_GET , $_POST , $_REQUEST , $_SERVER o $_COOKIE . $_SESSION tuttavia è diverso perché spesso desideri scrivere i dati nella sessione che viene poi mantenuta su richieste diverse nella sessione.

    
risposta data 13.05.2011 - 01:12
fonte
3

Dovresti evitarlo. Forse un po 'di tempo hai dimenticato di disinfettare qualcosa, quindi puoi recuperare dati pericolosi. Se copi i dati in una nuova struttura mentre stai disinfettando

  • Ottieni, ciò che vuoi / hai bisogno e non ciò che è in $_POST troppo
  • Probabilmente otterrai un errore, se l'array appena creato manca di alcune chiavi o non è presente affatto

Ulteriori altri script possono assumere che l'array non sia intoccato e possa suscitare reazioni.

    
risposta data 13.05.2011 - 01:12
fonte
1

Penso che la vera domanda qui sia "perché dovresti modificare il tema?". Non vedo alcuna ragione valida per farlo. Se hai bisogno di disinfettare un imput, potresti voler usare una variabile locale ...

A meno che il tuo codice non sia abbastanza breve (per esempio, lungo meno di 50 righe), la modifica di quelle super-globali renderebbe il tuo codice più difficile da mantenere e da sottomettere.

Tra l'altro non è necessario passare $ _POST alla funzione, poiché si tratta di un array superglobale a cui è possibile accedere anche all'interno dell'ambito locale di una funzione.

    
risposta data 13.05.2011 - 01:27
fonte
1

Non mi è mai piaciuta l'idea di modificare il superglobale perché è fuorviante. È un modo hacky veloce per fare qualcosa che probabilmente sarà un modo migliore di fare.

Se modifichi il valore di $_POST , ad esempio, stai dicendo che il software ha ricevuto dati che non ha.

IL VERO PROBLEMA

C'è una situazione di vita reale in cui questo diventa un grosso problema:

Immagina di lavorare in una squadra. In un mondo ideale, tutti usano la stessa sintassi, ma non viviamo in un mondo ideale. Uno sviluppatore, John, adora accedere ai dati pubblicati utilizzando $_POST . Cambia qualcosa nel post vars:

$_POST['ranking'] = 2; // John has changed ranking from 1 to 2 for whatever reason

Quindi hai un altro sviluppatore, Chris, che preferisce utilizzare filter_input per accedere ai dati immessi (cioè GET, POST, SERVER, COOKIE) mentre vengono utilizzati per proteggere il software durante l'elaborazione dei dati che l'utente può manomettere. Nella sua parte del software, ha bisogno di ottenere il valore post di ranking . La sua parte del codice è DOPO John's.

$ranking = filter_input(INPUT_POST, 'ranking', FILTER_SANITIZE_NUMBER_INT);
// $ranking = 1

Dall'esempio sopra, cambiando un superglobale, hai rotto PHP. John ha impostato il valore di $_POST['ranking'] su 2 per qualsiasi motivo, ma ora Chris ha ricevuto il valore 1

Quando non ho visto nessun altro modo per farlo:

Ho lavorato a un progetto che utilizzava wordpress come blog dietro un load balancer di AWS. Questo cambia il valore di $_SERVER['remote_address'] . In questo caso, l'altro sviluppatore non ha avuto altra scelta che eseguire quanto segue:

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $parts = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    $_SERVER['REMOTE_ADDR'] = $parts[0];
}

Conclusione

Certamente c'è un modo migliore di cambiare i superglobali

    
risposta data 30.06.2017 - 12:00
fonte
0

Dopo aver inizialmente risposto a questa domanda dicendo che non ci dovrebbero essere motivi per modificare i superglobali, sto modificando questa risposta con un esempio di un tempo in cui ho deciso di farlo.

Attualmente sto lavorando a una tabella di database di riscrittura di URL in cui la colonna request indirizza l'utente alla colonna target corrispondente.

Ad esempio, un request potrebbe essere blog/title-here e il suo target potrebbe essere blog.php?id=1 .

Poiché blog.php si aspetta $_GET variabili, e non voglio cambiare header("Location:") , mi viene lasciato fare qualcosa del genere:

$uri    = explode('?', $uri_request)[0];
$params = explode('?', $uri_request)[1];
parse_str($params, $_GET);

Crea una matrice $_GET contenente i parametri previsti passati dalla colonna target .

In definitiva, sconsiglio vivamente di modificare i superglobali a meno che non sia assolutamente necessario .

    
risposta data 11.02.2014 - 12:23
fonte

Leggi altre domande sui tag