Come preparare correttamente un'istruzione SQL %LIKE%?
Vorrei utilizzare un'istruzione LIKE %text% continuando a usare la classe WordPress $wpdb per sanitizzare e preparare l'input.
SELECT column_1 from `prefix_my_table` WHERE column_2 LIKE '%something%';
Ho provato qualcosa del genere senza successo:
$wpdb->prepare( "SELECT column_1 from `{$wpdb->base_prefix}my_table` WHERE column_2 LIKE %s;", like_escape($number_to_put_in_like));
Come si prepara correttamente un'istruzione SQL %LIKE% utilizzando la classe database di WordPress?
La funzione $wpdb->esc_like
esiste in WordPress perché l'escape regolare del database non gestisce i caratteri %
e _
. Ciò significa che puoi inserirli negli argomenti di wpdb::prepare()
senza problemi. Questo è anche quello che vedo nel codice core di WordPress:
$wpdb->prepare(" AND $wpdb->usermeta.meta_key = '{$wpdb->prefix}capabilities' AND $wpdb->usermeta.meta_value LIKE %s", '%' . $this->role . '%');
Quindi il tuo codice dovrebbe apparire così:
$wpdb->prepare(
"SELECT
column_1
FROM
`{$wpdb->base_prefix}my_table`
WHERE
column_2 LIKE %s;",
'%' . $wpdb->esc_like($number_to_put_in_like) . '%'
);
Puoi anche aggiungere %%
nella tua query per ottenere un %
letterale (wpdb::prepare()
utilizza vsprintf()
in background, che ha questa sintassi), ma ricorda che la tua stringa non sarà quotata, devi aggiungere tu stesso le virgolette (cosa che di solito non devi fare in wpdb::prepare()
).

@FranciscoCorralesMorales: Per indicare che tutto ciò che è al loro interno dovrebbe essere considerato un'espressione variabile, altrimenti vedrebbe solo $wpdb
e ignorerebbe il ->prefix
successivo.

@JanFabry Quasi giusto. Correggerei il commento dicendo: "... altrimenti vedrebbe tutto $wpdb->base_prefixmy_table
e cercherebbe di cercare la proprietà base_prefixmy_table
invece del solo base_prefix
.

Un'altra cosa da menzionare è che i % vengono sostituiti con un hash incredibilmente lungo. Che sembra sbagliato quando si fa var_dump dell'output SQL. Dopo ore di ricerca si nota qui che si tratta di una correzione di sicurezza per SQL injection in WordPress 4.8.3. https://stackoverflow.com/a/57914094/7977916

È necessario raddoppiare le percentuali in modo che non vengano trattate come marcatori di frammento da wpdb->prepare()
:
$wpdb->prepare( "SELECT column_1 from `{$wpdb->base_prefix}my_table` WHERE column_2 LIKE %%%s%%;", $wpdb->esc_like( $number_to_put_in_like));
PS non sono sicuro che questo sia il modo migliore/unico per farlo.

Ricorda che devi aggiungere tu le virgolette attorno alla stringa, perché wpdb::prepare
aggiungerà le virgolette solo per un %s
che non è preceduto da un %
. La parte finale della tua query dovrebbe essere WHERE column_2 LIKE '%%%s%%'
.

Questa soluzione ha funzionato alla grande insieme al suggerimento di @JanFabry

Questo è un metodo che ho verificato e funziona:
$search_text = "%" . $_GET['some_text'] . "%";
$user_count = $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(*) FROM mix_library WHERE ml_setting_name LIKE %s",
$search_text
)
);
Sostituisci le variabili in base alle tue esigenze.

Dovresti proteggere i caratteri %
(utilizzando like_escape()
. Vedi: http://codex.wordpress.org/Class_Reference/wpdb#Protect_Queries_Against_SQL_Injection_Attacks

Quindi il tuo approccio consiste nel passare una stringa casuale a prepare() e sostituirla con le percentuali in seguito? Sembra che tu stia combattendo con WordPress.
