web-dev-qa-db-de.com

Verwenden von $ wpdb zum Abfragen von Posts mit einem Metawert, der die aktuelle post_id enthält

Ich versuche, mit $ wpdb eine Liste der Posts aus der Datenbank abzurufen, wobei der Metawert in der Tabelle wp_postmeta die aktuelle Post-ID in Anführungszeichen enthält. z.B. "10"

Die Anführungszeichen stellen sicher, dass 10 nicht mit 100 übereinstimmt.

Ich kann es zum Laufen bringen, wenn ich den exakten Metawert einfüge, dh: a: 1: {i: 0; s: 2: "10";}, aber es werden auch alle Revisionen zurückgegeben, nicht nur die neuesten Post.

Hier ist der Code, den ich gerade benutze:

 $ id = get_the_ID (); 
 $ rows = $ wpdb-> get_results ($ wpdb-> prepare (
 "
 SELECT * 
 FROM wp_postmeta 
 WHERE meta_key LIKE% s 
 AND meta_value =% s 
 ", 
 'Rolls _% _ production', 
 '%"'. $ id. '"%' 
); 
 
 // die Ergebnisse durchlaufen 
 if ($ rows) {
 ... ... 
} 

Irgendwelche Ideen wären sehr dankbar.

Vielen Dank

2
Matt Edwards

In dem Code, den Sie gepostet haben, rufen Sie nicht wie gesagt die "Liste der Beiträge" ab, sondern eine Liste der Zeilen in der Metatabelle. Wenn Sie wirklich eine Liste von Beiträgen abrufen möchten, verlassen Sie sich auf WP_Query mit meta_query param.

So etwas wie:

$id = '10'; // unserialized value

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

Wenn Sie $ wpdb verwenden möchten (ich weiß nicht warum), lautet die richtige Abfrage wie folgt:

<?php
$id = '10'; // unserialized value

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 enthält eine Reihe von Beitrags-IDs. Ich habe diese Änderung vorgenommen, um die Verwendung von $ wpdb sinnvoll zu gestalten. Wenn Sie alle Felder abrufen möchten, verwenden Sie SELECT * anstelle von SELECT DISTINCT $wpdb->posts.ID, verwenden Sie $wpdb->get_results anstelle von $wpdb->get_col und fügen Sie der Abfrage die Zeile GROUP BY $wpdb->posts.ID hinzu.

6
gmazzap

Zwei Notizen:

Suche nach Metadaten

Die Regel ist einfach: Serialisierte Metadaten (wie ein in a:1:{i:0;s:2:"10";} konvertiertes Array)sollen nicht durchsuchbar sein. Sie müssen Ihr Dataset in einzelne Werte konvertieren, damit Sie die richtigen meta_query-Suchen durchführen können.

Die einzige Möglichkeit, dies zu durchsuchen, besteht darin, all die Daten abzufragen, sie dann zu deserialisieren, sie zu rendern, wenn sie Ihren Kriterien entsprechen, oder sie zu überspringen. Es gibt genug Diskussionen und Q/As zu SO, die dieses Thema behandeln .

Vorbereitete Aussagen

Es gibt like_escape() , das wie folgt verwendet werden muss:

"%".like_escape( $string )."%"

Der Grund, warum Sie die %-Zeichen vor- und anhängen müssen, ist einfach: Sie können selbst entscheiden, ob die LIKE an beiden Enden oder nur an einem einzigen (Anfang, Ende, beide Seiten) auftreten soll.

1
kaiser

Die Anführungszeichen stellen sicher, dass 10 nicht mit 100 übereinstimmt.

Ich kann es funktionieren lassen, wenn ich den exakten Metawert einfüge, dh: a: 1: {i: 0; s: 2: "10";}

Dies liegt daran, dass Sie in Ihrer WHERE-Abfrage = verwendet haben, wobei der Wert % enthält. Die Verwendung von LIKE würde dieses spezielle Problem beheben. Ändern Sie meta_value = %s in meta_value LIKE %s, und Ihre Abfrage sollte genauso funktionieren, als ob Sie die vollständige serialisierte Zeichenfolge verwendet hätten.

es werden auch alle Überarbeitungen zurückgegeben, nicht nur der neueste Beitrag.

Stellen Sie sicher, dass Sie den richtigen Beitragstyp und -status angeben, wenn Sie Ihre Ergebnisse abfragen. Wenn Sie alle Posts einschließen möchten, die keine Revisionen sind, müssen Sie sicherstellen, dass Sie der Posts-Tabelle beitreten (vor Ihrer WHERE-Anweisung).

LEFT JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->postmeta.post_id

fügen Sie die folgende Zeile in Ihre WHERE-Anweisung ein (durch eine AND verknüpft).

$wpdb->posts.post_type NOT IN ('revision')
0
Shaun Cockerill