Le regole per aggiungere una variabile PHP all'interno di qualsiasi istruzione MySQL sono chiare e semplici:
- Qualsiasi variabile che rappresenta un valore letterale di dati SQL , (o, per dirla semplicemente, una stringa SQL o un numero) DEVE essere aggiunto tramite un'istruzione preparata. Nessuna eccezione.
- Qualsiasi altra parte della query, come una parola chiave SQL, una tabella o un nome di campo o un operatore, deve essere filtrata tramite una lista bianca .
Quindi, poiché il tuo esempio coinvolge solo valori letterali di dati, tutte le variabili devono essere aggiunte tramite segnaposto (chiamati anche parametri). Per farlo:
- Nella tua istruzione SQL, sostituisci tutte le variabili con segnaposto
- preparare la query risultante
- legare variabili ai segnaposto
- esegui la domanda
Ed ecco come farlo con tutti i driver di database PHP più diffusi:
Aggiunta di valori letterali di dati utilizzando mysql ext
Tale driver non esiste .
Aggiunta di valori letterali di dati utilizzando mysqli
$type = 'testing';
$reporter = "John O'Hara";
$query = "INSERT INTO contents (type, reporter, description)
VALUES(?, ?, 'whatever')";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("ss", $type, $reporter);
$stmt->execute();
Il codice è un po' complicato ma la spiegazione dettagliata di tutti questi operatori può essere trovata nel mio articolo, Come eseguire un INSERT query utilizzando Mysqli , oltre a una soluzione che semplifica notevolmente il processo.
Per una query SELECT dovrai aggiungere solo una chiamata a get_result()
metodo per ottenere un familiare mysqli_result
da cui puoi recuperare i dati nel solito modo:
$reporter = "John O'Hara";
$stmt = $mysqli->prepare("SELECT * FROM users WHERE name=?");
$stmt->bind_param("s", $reporter);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc(); // or while (...)
Aggiunta di valori letterali di dati utilizzando PDO
$type = 'testing';
$reporter = "John O'Hara";
$query = "INSERT INTO contents (type, reporter, description)
VALUES(?, ?, 'whatever')";
$stmt = $pdo->prepare($query);
$stmt->execute([$type, $reporter]);
In PDO, possiamo combinare le parti di rilegatura ed esecuzione, il che è molto conveniente. PDO supporta anche i segnaposto denominati che alcuni trovano estremamente convenienti.
Aggiunta di parole chiave o identificatori
A volte dobbiamo aggiungere una variabile che rappresenta un'altra parte di una query, come una parola chiave o un identificatore (un database, una tabella o un nome di campo). È un caso raro ma è meglio essere preparati.
In questo caso, la tua variabile deve essere confrontata con un elenco di valori esplicitamente scritto nella tua sceneggiatura. Questo è spiegato nel mio altro articolo, Aggiunta di un nome di campo nella clausola ORDER BY in base alla scelta dell'utente :
Sfortunatamente, PDO non ha segnaposto per gli identificatori (nomi di tabelle e campi), quindi uno sviluppatore deve filtrarli manualmente. Tale filtro è spesso chiamato "lista bianca" (in cui elenchiamo solo valori consentiti) anziché "lista nera" in cui elenchiamo valori non consentiti.
Quindi dobbiamo elencare esplicitamente tutte le possibili varianti nel codice PHP e quindi scegliere da esse.
Ecco un esempio:
$orderby = $_GET['orderby'] ?: "name"; // set the default value
$allowed = ["name","price","qty"]; // the white list of allowed field names
$key = array_search($orderby, $allowed, true); // see if we have such a name
if ($key === false) {
throw new InvalidArgumentException("Invalid field name");
}
Esattamente lo stesso approccio dovrebbe essere utilizzato per la direzione,
$direction = $_GET['direction'] ?: "ASC";
$allowed = ["ASC","DESC"];
$key = array_search($direction, $allowed, true);
if ($key === false) {
throw new InvalidArgumentException("Invalid ORDER BY direction");
}
Dopo tale codice, entrambi $direction
e $orderby
le variabili possono essere inserite in modo sicuro nella query SQL, poiché sono uguali a una delle varianti consentite o verrà generato un errore.
L'ultima cosa da menzionare sugli identificatori, devono anche essere formattati in base alla particolare sintassi del database. Per MySQL dovrebbe essere backtick
caratteri intorno all'identificatore. Quindi la stringa di query finale per il nostro ordine per esempio sarebbe
$query = "SELECT * FROM `table` ORDER BY `$orderby` $direction";