Folosirea $wpdb pentru a interoga postări cu valoare meta care conține post_id curent
Încerc să utilizez $wpdb pentru a prelua o listă de postări din baza de date unde meta_value din tabelul wp_postmeta conține post_ID-ul curent între ghilimele. De exemplu: "10".
Ghilimelele sunt folosite pentru a mă asigura că 10 nu se potrivește și cu 100 etc.
Funcționează când introduc exact valoarea meta, adică: a:1:{i:0;s:2:"10";}, dar returnează și toate reviziile, nu doar cea mai recentă postare.
Iată codul pe care îl folosesc în prezent:
$id = get_the_ID();
$rows = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM wp_postmeta
WHERE meta_key LIKE %s
AND meta_value = %s
",
'roles_%_production',
'%"' . $id . '"%'
));
// buclă prin rezultate
if( $rows ) {
......
}
Orice sugestii ar fi foarte apreciate.
Mulțumesc

În codul postat de tine nu preiei 'lista de articole' cum spui, ci preiei o listă de rânduri din tabela meta. Dacă vrei să preiei cu adevărat o listă de articole, folosește WP_Query
cu parametrul meta_query
.
Ceva de genul:
$id = '10'; // valoare neserializată
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'roles_%_production',
'value' => $id,
'compare' => 'LIKE'
)
)
);
$query = new WP_Query( $args );
$rows = $query->get_posts();
Dacă vrei să folosești $wpdb (nu știu de ce) interogarea corectă ar fi ceva de genul:
<?php
$id = '10'; // valoare neserializată
global $wpdb;
$rows = $wpdb->get_col( $wpdb->prepare(
"SELECT DISTINCT $wpdb->posts.ID FROM $wpdb->posts, $wpdb->postmeta
WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id AND
$wpdb->posts.post_status = 'publish' AND
$wpdb->posts.post_type = 'post' AND
$wpdb->postmeta.meta_key = %s AND
meta_value = %s",
'roles_%_production',
$id
) );
?>
$rows
va conține un array cu ID-urile articolelor. Am făcut această modificare pentru a da sens folosirii lui $wpdb. Dacă vrei să preiei toate câmpurile, folosește SELECT *
în loc de SELECT DISTINCT $wpdb->posts.ID
, folosește $wpdb->get_results
în loc de $wpdb->get_col
și adaugă linia GROUP BY $wpdb->posts.ID
la interogare.

Două observații:
Căutarea metadatelor
Regula este simplă: Metadatele serializate (cum ar fi un array convertit în a:1:{i:0;s:2:"10";}
) nu sunt concepute pentru a fi căutabile. Va trebui să convertiți setul de date în valori individuale, astfel încât să puteți efectua căutări corecte cu meta_query
.
Singura modalitate care funcționează cu adevărat pentru a căuta aceste date este să interogați toate datele, apoi să le deserializați, să le afișați dacă se potrivesc cu criteriile dvs. sau să le săriți. Există suficiente discuții și întrebări/răspunsuri pe SO care acoperă acest subiect.
Interogări pregătite (Prepared statements)
Există like_escape()
, care trebuie utilizat astfel:
"%".like_escape( $string )."%"
Motivul pentru care trebuie să adăugați caracterele %
înainte și după este simplu: Puteți decide dacă LIKE
trebuie aplicat la ambele capete sau doar la unul singur (început, sfârșit sau ambele părți).

Ghilimelele inverse sunt folosite pentru a se asigura că 10 nu se potrivește și cu 100 etc.
Funcționează când lipesc valoarea exactă a meta valorii, adică: a:1:{i:0;s:2:"10";}
Aceasta se întâmplă deoarece în interogarea WHERE ați folosit =
în timp ce valoarea conține %
. Folosirea lui LIKE
în loc ar rezolva această problemă specifică. Schimbați meta_value = %s
în meta_value LIKE %s
, iar interogarea dvs. ar trebui să funcționeze la fel ca și când ați folosit șirul serializat complet.
De asemenea, returnează toate reviziile, nu doar cel mai recent post.
Asigurați-vă că specificați tipul corect de postare și statusul atunci când interogați rezultatele. Dacă doriți să includeți toate postările care nu sunt revizii, atunci va trebui să vă asigurați că alăturați tabelul posts (înainte de instrucțiunea WHERE
).
LEFT JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->postmeta.post_id
și includeți următoarea linie în instrucțiunea dvs. WHERE
(legată printr-un AND
).
$wpdb->posts.post_type NOT IN ('revision')
