Dovrei usare wpdb prepare?
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

È 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

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..!

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!

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"`.

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 Se rileggi la risposta vedrai che in realtà dici la stessa cosa che ho detto io, e che il nome della tabella è un esempio.

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....

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

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.

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.
