Dovrei usare wpdb prepare?

11 mag 2011, 10:16:11
Visualizzazioni: 58.6K
Voti: 38

Sono nuovo in SQL e mi chiedo se devo usare wpdb->prepare per la seguente query su una tabella che ho creato

global $wpdb;
$tablename = $wpdb->prefix . "my_custom_table";
$sql = "SELECT * FROM " . $tablename . " ORDER BY date_created DESC";
$resulst = $wpdb->get_results( $sql , ARRAY_A );

Devo usare prepare qui? Come dovrei farlo?

Grazie

0
Tutte le risposte alla domanda 3
7
47

È considerata una best practice utilizzare sempre prepare, ma il suo utilizzo principale è prevenire attacchi di SQL injection. Dal momento che nel tuo esempio attuale non c'è input da parte degli utenti/visitatori o non possono influenzare la query, questo non rappresenta un problema.

Ma come ho detto prima, è una best practice usarlo e una volta che inizi a utilizzarlo non smetti più, quindi nel tuo esempio puoi usarlo in questo modo:

global $wpdb;
$tablename = $wpdb->prefix . "my_custom_table";
$sql = $wpdb->prepare( "SELECT * FROM %s ORDER BY date_created DESC",$tablename );
$results = $wpdb->get_results( $sql , ARRAY_A );

Per saperne di più su come utilizzarlo, vai alla codex

11 mag 2011 10:43:00
Commenti

Ciao @Bainternet, grazie per una spiegazione così chiara - per qualche motivo quando provo il tuo codice restituisce un array vuoto. Ho controllato e ricontrollato eventuali errori di battitura. Se eseguo la query non preparata ottengo l'array. Non capisco perché non funzioni..!

Richard Sweeney Richard Sweeney
11 mag 2011 11:03:09

Strano. Ho provato a usare lo stesso codice con un'altra query: `$tablename = $wpdb->prefix . "my_custom_table"; $concert_id = 1;

$sql = "SELECT * FROM " . $tablename . " WHERE concert_id = %d LIMIT 1;";

$prep_sql = $wpdb->prepare( $sql, $concert_id );

$get_concerts = $wpdb->get_results( $prep_sql , ARRAY_A );`

E funziona benissimo! Non sono sicuro del perché. Ma ora ho capito in ogni caso!

Richard Sweeney Richard Sweeney
11 mag 2011 11:36:02

Racchiudere il nome della tabella tra apici singoli non funzionerà. L'escape normale si fa con i backtick, quindi la tua query dovrebbe risultare così: SELECT * FROM \wp_my_custom_table`. Puoi abilitare il supporto per i doppi apici, ma allora dovrebbe essere così:SELECT * FROM "wp_my_custom_table"`.

Jan Fabry Jan Fabry
11 mag 2011 11:52:17

Non sono d'accordo con questa risposta. Perché dovresti effettuare l'escape quando la funzione già esegue l'escape di tutto? Pensi che WordPress deciderà di rimuovere l'escape dal core? Inoltre non ha senso eseguire l'escape del nome della tabella :) perché è hardcoded e sai che va bene. So che questo è solo un esempio ma comunque non eseguire l'escape dei nomi delle tabelle, ho avuto problemi quando uso prepare con i nomi delle tabelle aggiunge backtick e SQL restituisce errore.

Tommixoft Tommixoft
4 nov 2014 14:41:44

@Tommixoft Se rileggi la risposta vedrai che in realtà dici la stessa cosa che ho detto io, e che il nome della tabella è un esempio.

Bainternet Bainternet
5 nov 2014 09:07:36

Puoi supportare l'affermazione che è una best practice? Sembra strano (come non best practice) usare una funzione che è non necessaria e si aspetta 2+ parametri in questo caso....

random_user_name random_user_name
14 ott 2016 17:23:32

Ahhh la risposta è del 2011!!! Se accetti input dall'utente nella query allora sì, è sempre una best practice.

Bainternet Bainternet
20 ott 2016 17:27:15
Mostra i restanti 2 commenti
2

Quando utilizzi prepare stai proteggendo il codice da vulnerabilità di SQL injection.

Ecco il codice che devi modificare per utilizzare prepare():

global $wpdb;
$tablename = $wpdb->prefix . "my_custom_table";
$sql = $wpdb->prepare( "SELECT * FROM {$tablename} ORDER BY date_created DESC");
$resulst = $wpdb->get_results( $sql , ARRAY_A );
12 ott 2015 18:34:35
Commenti

Solo perché usi prepare() il codice non è automaticamente protetto contro le SQL injection. Il tuo codice potrebbe far pensare che $tablename sia protetto contro le SQL injection perché viene usato in prepare, ma non è così, poiché non viene fornito tramite gli argomenti. In questo caso non è un problema perché il contenuto di $tablename è sicuro, ma penso che sarebbe bene chiarirlo.

Constantin Constantin
28 dic 2020 17:04:58

Sì. Questa risposta è sbagliata e direi pericolosamente fuorviante. Hai chiamato prepare in un modo che in realtà non protegge dalle SQL injection.

Harry Wood Harry Wood
11 nov 2021 13:30:10
0

Nel tuo caso non è possibile un attacco SQL injection. Il tuo codice non necessita di ulteriore protezione perché non utilizza input utente come: post, get, request, cookie.

Non utilizzare funzioni complicate quando non sono necessarie per risparmiare risorse del server.

17 lug 2015 11:51:54