ottenere tutti i valori per una chiave di campo personalizzata (cross-post)


44

So come ottenere un valore di campo personalizzato per un post specifico.

get_post_meta($post_id, $key, $single);

Ciò di cui ho bisogno è ottenere tutti i valori associati a una chiave di post personalizzata specifica, in tutti i post .

Qualcuno sa di un modo efficace per farlo? Non vorrei scorrere tutti gli ID post nel DB.

Esempio:

4 post tutti con valori diversi per un campo personalizzato chiamato "Mood". 2 post hanno il valore 'felice', 1 post ha 'arrabbiato' e 1 post ha 'triste'

Voglio pubblicare: su tutti i post che abbiamo: due autori felici, uno arrabbiato e uno triste.

Ma per MOLTI post.

Quello che sto cercando è:

  • una funzione WP per ottenere questo. o
  • una query personalizzata per ottenerla nel modo più efficiente possibile.

5
Sembra che tu stia usando questo come una tassonomia. Perché non semplicemente (automaticamente) aggiungere un termine a questi post durante il salvataggio? Renderebbe l'interrogazione molto più semplice.
Kaiser,

@kaiser Non posso ringraziarti abbastanza per essere un genio!
user2128576,

Risposte:


58

Un possibile approccio sarebbe quello di utilizzare uno dei metodi di supporto nella classe WPDB per eseguire una query meta-based più raffinata. L'avvertenza nell'uso di alcune di queste funzioni, tuttavia, è che di solito non si ottiene indietro una semplice matrice di dati e di solito si devono fare riferimenti inutili alle proprietà degli oggetti, anche se si richiede solo una colonna o riga.

Naturalmente, non tutte le funzioni sono la stessa cosa e una menzione intenzionale va al metodo WPDB , get_colche restituisce un semplice array piatto dei dati richiesti, faccio questa menzione specificamente perché l'esempio che segue farà appello a questo metodo .

WordPress - WPDB Selezione di una colonna di dati
$ wpdb-> get_col ()

Ecco una funzione di esempio che interroga il database per tutti i post di un tipo di post scelto, lo stato dei post e con una meta chiave specifica (o un campo personalizzato per i meno esperti tecnicamente).

function get_meta_values( $key = '', $type = 'post', $status = 'publish' ) {

    global $wpdb;

    if( empty( $key ) )
        return;

    $r = $wpdb->get_col( $wpdb->prepare( "
        SELECT pm.meta_value FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = %s 
        AND p.post_status = %s 
        AND p.post_type = %s
    ", $key, $status, $type ) );

    return $r;
}

Quindi, ad esempio, se ti piace scoprire quali post hanno una meta chiave di valutazione , per i filmati di tipo post e desideri archiviare tali informazioni all'interno di una variabile, un esempio di tale chiamata sarebbe ..

$movie_ratings = get_meta_values( 'rating', 'movies' );

Se non volevi fare altro che stampare quei dati sullo schermo, la funzione di implosione di PHP può rapidamente suddividere quel semplice array in linee di dati.

// Print the meta values seperate by a line break
echo implode( '<br />', get_meta_values( 'YOURKEY' ));

Puoi anche utilizzare i dati restituiti per capire quanti post hanno questi meta valori facendo un semplice ciclo sui dati restituiti e costruendo una matrice di conteggi, ad esempio.

$movie_ratings = get_meta_values( 'rating', 'movies' );
if( !empty( $movie_ratings ) ) {
    $num_of_ratings = array();
    foreach( $movie_ratings as $meta_value )
        $num_of_ratings[$meta_value] = ( isset( $num_of_ratings[$meta_value] ) ) ? $num_of_ratings[$meta_value] + 1 : 1;
}

/*
Result:
Array(
    [5] => 10
    [9] => 2
)
// ie. there are 10 movie posts with a rating of 5 and 2 movie posts with a rating of 9.
*/

Questa logica potrebbe essere applicata a vari tipi di dati ed estesa per funzionare in diversi modi. Quindi spero che i miei esempi siano stati utili e abbastanza semplici da seguire.


3
Un fatto divertente anche per i futuri spettatori, se vuoi estrarre solo meta valori unici: digiti DISTINCTsubito dopo SELECTnella funzione sopra. Potrebbe essere utile
Howdy_McGee

Penso che questo sia estremamente utile
Pablo SG Pacheco,

Come fare questo, e restituire i valori ordinati ?, Penso che usando ORDER da ma non riesco a capire come usarlo
efirvida

14

Vorrei solo aggiungere una piccola cosa al codice di t31os sopra. Ho cambiato "SELEZIONA" in "SELEZIONA DISTINCT" per eliminare voci duplicate quando ho usato questo codice da solo.


1
Posso immaginare casi in cui sarebbe valido avere più meta valori dello stesso valore, e quindi non apportare quell'aggiunta al mio codice. Se vuoi valori distinti, questa sarebbe la strada da percorrere. Inoltre, puoi anche aggiungerlo come argomento per la funzione (in modo da poterlo utilizzare o meno, a seconda dei casi).
t31os,

10

Non è buono o necessario utilizzare $ wpdb globale:

// function to grab all possible meta values of the chosen meta key.
function get_meta_values( $meta_key,  $post_type = 'post' ) {

    $posts = get_posts(
        array(
            'post_type' => $post_type,
            'meta_key' => $meta_key,
            'posts_per_page' => -1,
        )
    );

    $meta_values = array();
    foreach( $posts as $post ) {
        $meta_values[] = get_post_meta( $post->ID, $meta_key, true );
    }

    return $meta_values;

}

$meta_values = get_meta_values( $meta_key, $post_type );

Questo sarebbe il mio metodo preferito per farlo, nella maggior parte dei casi. Esegue cinque query, anziché solo una, ma, poiché utilizza le procedure WordPress standard per generarle e inviarle, verrà avviata qualsiasi cache specifica per la piattaforma (come la cache degli oggetti di WP Engine o alcuni plugin casuali). I dati verranno inoltre avviati essere archiviato nella cache interna di WordPress per la durata della richiesta, quindi non sarà necessario recuperarlo nuovamente dal database, se necessario.
Andrew Dinmore,

Eventuali filtri verranno inoltre applicati ai dati, il che potrebbe essere estremamente importante, ad esempio, su un sito multilingue. Infine, poiché utilizza solo le funzioni standard di WordPress, è molto meno probabile che venga interrotto da un aggiornamento futuro.
Andrew Dinmore,

4

il modo più veloce sarebbe una query sql personalizzata e non sono sicuro, ma puoi provare

$wpdb->get_results("
  SELECT posts.* , COUNT(*) 'moodcount'
  FROM $wpdb->posts as posts
  JOIN $wpdb->postmeta as postmeta
  ON postmeta.post_id = posts.ID
  AND postmeta.meta_key = 'Mood'
  GROUP BY postmeta.meta_key
");

Se mai, allora è un inizio.


1
grazie, ma le domande personalizzate non dovrebbero essere evitate "a tutti i costi"? Preferirei usare lo strato di astrazione WP (è così che si chiama?) ... ma ovviamente se questo non è possibile ..
mikkelbreum

Le query personalizzate, se scritte nel modo giusto, possono essere migliori e dovresti evitarle solo se non sai cosa stai facendo.
Bainternet,

1
Sono d'accordo con le query mwb .custom sono molto utili e pratiche, ma penso che siano anche molto più pesanti sul DB .. specialmente usando le funzioni SRT ..
krembo99

3

Per ottenere tutti i meta valori con una meta chiave

Controlla il codice wordpress wp-> db

$values = $wpdb->get_col("SELECT meta_value
    FROM $wpdb->postmeta WHERE meta_key = 'yourmetakey'" );

3
Il problema con questo approccio è la mancanza di specificità, otterrai numerosi risultati da una tale query, che potrebbe includere bozze, elementi nel cestino, post, pagine e qualsiasi altro tipo di post esistente. Non dovresti mai chiedere ciò che non ti serve, la specificità è sicuramente richiesta qui.
t31os,

Sebbene sia vero che potresti ottenere valori da altri tipi e stati di post, ci sono momenti in cui tutto ciò di cui hai bisogno sono i valori e non hai usato quella meta_key ovunque ma dove ne hai bisogno. Se tutti / la maggior parte dei valori sono unici, questa potrebbe essere la soluzione migliore.
Luke Gedeon,

2

Non c'è motivo per cui non è possibile unire t31os e il codice di Bainternet per avere un'istruzione preparata riutilizzabile (stile wordpress) che restituisce il conteggio e i valori in un'unica operazione efficiente.

È una query personalizzata ma utilizza ancora il livello di astrazione del database wordpress, quindi ad esempio non importa quali siano i nomi delle tabelle o se cambiano, ed è un'istruzione preparata, quindi siamo molto più sicuri dagli attacchi SQL ecc. .

In questo caso non sto più controllando il tipo di post e escludo stringhe vuote:

    $r = $wpdb->get_results(  $wpdb->prepare( "
        SELECT pm.meta_value AS name, count(*) AS count  FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = '%s'
        AND pm.meta_value != '' 
        AND p.post_type = '%s'
        GROUP BY pm.meta_value
        ORDER BY pm.meta_value          
        ", $key, $type) 
        );
    return $r;

In questo particolare è

Ciò restituirà una matrice di oggetti in questo modo:

array  
 0 => 
 object(stdClass)[359]
  public 'name' => string 'Hamish' (length=6)
  public 'count' => string '3' (length=1)
 1 => 
 object(stdClass)[360]
  public 'name' => string 'Ida' (length=11)
  public 'count' => string '1' (length=1)
 2 => 
 object(stdClass)[361]
  public 'name' => string 'John' (length=12)
  public 'count' => string '1' (length=1)

0

Utilizzare quanto segue con foreach

 $key = get_post_custom_values( 'key' );

Presuppone che il nome della chiave di campo personalizzata sia


Si noti che per impostazione predefinita è il post corrente, quando non viene specificato post_id.
birgire,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.