Cum pregătești corect o declarație SQL cu %LIKE%?
Aș dori să folosesc o declarație LIKE %text% folosind în același timp clasa WordPress $wpdb pentru a securiza și pregăti datele de intrare.
SELECT column_1 from `prefix_my_table` WHERE column_2 LIKE '%something%';
Am încercat ceva de genul acesta fără succes:
$wpdb->prepare( "SELECT column_1 from `{$wpdb->base_prefix}my_table` WHERE column_2 LIKE %s;", like_escape($number_to_put_in_like));
Cum pregătești corect o declarație SQL cu %LIKE% folosind clasa de baze de date WordPress?
Funcția $wpdb->esc_like
există în WordPress deoarece escaparea obișnuită a bazei de date nu escapă caracterele %
și _
. Aceasta înseamnă că le puteți adăuga în argumentele dumneavoastră pentru wpdb::prepare()
fără probleme. Acest lucru este, de asemenea, ceea ce văd în codul de bază al WordPress:
$wpdb->prepare(" AND $wpdb->usermeta.meta_key = '{$wpdb->prefix}capabilities' AND $wpdb->usermeta.meta_value LIKE %s", '%' . $this->role . '%');
Deci codul dumneavoastră ar arăta astfel:
$wpdb->prepare(
"SELECT
column_1
FROM
`{$wpdb->base_prefix}my_table`
WHERE
column_2 LIKE %s;",
'%' . $wpdb->esc_like($number_to_put_in_like) . '%'
);
De asemenea, puteți adăuga %%
în interogarea dumneavoastră pentru a obține un caracter literal %
(wpdb::prepare()
utilizează vsprintf()
în fundal, care are această sintaxă), dar amintiți-vă că șirul dumneavoastră nu va fi citat, trebuie să adăugați singur ghilimelele (ceea ce nu este ceea ce trebuie de obicei să faceți în wpdb::prepare()
.

@FranciscoCorralesMorales: Pentru a indica că tot ce se află în interiorul acestora ar trebui considerat o expresie variabilă, altfel ar vedea doar $wpdb
și ar ignora ->prefix
după el.

@JanFabry Aproape. Aș corecta comentariul spunând: "... altfel ar vedea tot $wpdb->base_prefixmy_table
și ar încerca să caute proprietatea base_prefixmy_table
în loc de doar base_prefix
.

De asemenea, un lucru de menționat este că % sunt înlocuite cu un hash absurd de lung. Ceea ce arată greșit când folosești var_dump pentru output-ul SQL. După ore de căutare, s-a remarcat aici că aceasta este o remediere de securitate WordPress 4.8.3 pentru injecția SQL. https://stackoverflow.com/a/57914094/7977916

Trebuie să dublezi procentele astfel încât să nu fie tratate ca markeri de fragment de către 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: nu sunt sigur că aceasta este cea mai bună/singura metodă de a face acest lucru.

Ține minte că tu trebuie să adaugi ghilimelele în jurul șirului de caractere, deoarece wpdb::prepare
le va adăuga doar pentru un %s
care nu este precedat de un %
. Partea finală a interogării tale ar trebui să fie WHERE column_2 LIKE '%%%s%%'
.

Acesta este un mod de a face acest lucru pe care l-am verificat și funcționează:
$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
)
);
Înlocuiți variabilele pentru a se potrivi nevoilor dumneavoastră.

Ar trebui să evitați caracterele %
(folosind like_escape()
. Consultați: http://codex.wordpress.org/Class_Reference/wpdb#Protect_Queries_Against_SQL_Injection_Attacks

$safe_sql = $wpdb->prepare("SELECT * FROM $wp_track_table $sql",["*yoursecretkey*".$_POST['search']."*yoursecretkey*"]);
$safe_sql = str_replace("*yoursecretkey*", "%", $safe_sql);
Am găsit o soluție adecvată cu codurile de mai sus. Cu siguranță încercați această abordare.

Deci abordarea ta este să transmiți un șir aleatoriu în prepare() și să-l înlocuiești cu procente mai târziu? Asta se simte ca și cum te-ai lupta cu WordPress.
