Quando dovresti usare WP_Query vs query_posts () vs get_posts ()?


Risposte:


667
  • query_posts()è eccessivamente semplicistico e un modo problematico per modificare la query principale di una pagina sostituendola con una nuova istanza della query. È inefficiente (esegue nuovamente le query SQL) e fallirà completamente in alcune circostanze (soprattutto quando si ha a che fare con l'impaginazione dei post). Qualsiasi codice WP moderno dovrebbe utilizzare metodi più affidabili, come l'uso pre_get_postsdell'hook, per questo scopo. TL; DR non usa mai query_posts () .

  • get_posts() è molto simile nell'uso e accetta gli stessi argomenti (con alcune sfumature, come impostazioni predefinite diverse), ma restituisce una serie di post, non modifica le variabili globali ed è sicuro da usare ovunque.

  • WP_Queryè la classe che alimenta entrambi dietro le quinte, ma puoi anche creare e lavorare con la tua propria istanza. Un po 'più complesso, meno restrizioni, sicuro da usare ovunque.


8
@jjeaton query_posts()è una piccola funzione wrapper per WP_Query, l'unica cosa extra che fa (come da diagramma di flusso) è la sovrascrittura globale$wp_query
Rarst

7
@jjeaton La sostituzione query_posts()con WP_Querynon farà alcuna differenza nelle prestazioni, la query della pagina originale verrà comunque eseguita perché fa parte del carico principale. Queste query verranno eseguite anche se il file modello non ha alcun ciclo.
Rarst

116
Non riesco a liberarmi della sensazione che questo sia il post più geniale e votato su WPSE. Dovrebbe essere anche nel Codex.
Kaiser,

8
Aggiungerò solo la mia descrizione più chiara del problema "performance of query_posts ()": l'uso di query_posts () o WP_Query all'interno di un file modello avrà lo stesso costo performnace: la query appena eseguita. Il problema discusso nell'articolo del codice è che se si desidera effettivamente sostituire la query, è necessario filtrare il file query_posts () originale con il filtro "parse_query". In questo modo hai solo una query originale, desiderabile, invece di fare una seconda query per sostituirla goffamente. query_posts () è MAI IL MODO !! MAI!
jerclarke,

22
C'è una terrificante spiegazione di query_posts scritta da John James Jacoby sul blog developer.wordpress.com che fa esplodere tutte queste risposte. Il punto principale: query_postsnon modificare il ciclo principale a tutti, sostituisce esso dopo aver già eseguito. Il modo migliore per modificare il ciclo principale è attraverso un pre_get_postsfiltro. developer.wordpress.com/2012/05/14/…
Dan Gayle

65

query_posts- Non dovresti mai usare query_posts. A parte ciò che ha detto @Rarst, il vero problema query_postsè che rompe l'oggetto di query principale (archiviato in $wp_query). Molti plug-in e codice personalizzato si basano sull'oggetto query principale, quindi la rottura dell'oggetto query principale significa che si stanno rompendo le funzionalità dei plug-in e del codice personalizzato. Solo una di queste funzioni è l'importante funzione di impaginazione, quindi se si interrompe la query principale, si interrompe l'impaginazione.

Per dimostrare quanto query_postsè male , su qualsiasi modello, fai quanto segue e confronta i risultati

var_dump( $wp_query );
query_posts( '&posts_per_page=-1' );
var_dump( $wp_query );

get_postse WP_Querysono il modo corretto di costruire query secondarie ( come post correlati, cursori, contenuti in primo piano e contenuti su prime pagine statiche ) con. Va notato che non dovresti usare nessuno dei due a favore della query principale sulla home page, sulla singola pagina o su qualsiasi tipo di pagina di archivio poiché interromperà la funzionalità della pagina. Se è necessario modificare la query principale, utilizzare pre_get_postsper farlo e non una query personalizzata. ( AGGIORNAMENTO: per le prime pagine statiche e le vere pagine, vedere Utilizzo di pre_get_posts su pagine vere e prime pagine statiche *)

In sostanza, WP_Queryviene utilizzato dalla query principale e viene utilizzato anche da get_posts, ma sebbene get_posts()utilizzi WP_Query, ci sono alcune differenze

  • get_postssono più veloci di WP_Query. Il margine dipende dalla quantità di post totali del sito. Il motivo di ciò è, get_postspassa 'no_found_rows' => truedi default a WP_Querycui salta / interrompe legalmente l'impaginazione. Con 'no_found_rows' => true, WP_Queryottiene la quantità di post richiesti, quindi esce, dove per impostazione predefinita, cerca ulteriormente tutti i post corrispondenti alla query per calcolare l'impaginazione.

    Per questo motivo, get_posts()deve essere utilizzato solo per query non impaginate. La paginazione get_postsè davvero un gran casino. WP_Querydovrebbe essere usato per tutte le query impaginate

  • get_posts()non sono influenzati dai posts_*filtri dove WP_Queryvengono influenzati da questi filtri. Il motivo è che get_posts, per impostazione predefinita, passa 'suppress_filters' => trueaWP_Query

  • get_postsha un paio di parametri extra come include, exclude, numberpostse category. Questi parametri vengono modificati in parametri validi WP_Queryprima di essere passati a WP_Query. includeviene cambiato in post__in, excludein post__not_in, categoryin cate numberpostsin posts_per_page. Solo una nota, tutti i parametri che possono essere passati a WP_Querylavorare con get_posts, è possibile ignorare e non utilizzare i parametri predefiniti diget_posts

  • get_postsrestituisce solo la $postsproprietà di WP_Querywhile WP_Queryrestituisce l'oggetto completo. Questo oggetto è abbastanza utile quando si tratta di condizionali, impaginazione e altre informazioni utili che possono essere utilizzate all'interno del ciclo.

  • get_postsnon utilizza il loop, ma un foreachloop per visualizzare i post. Inoltre, per impostazione predefinita non sono disponibili tag modello. setup_postdata( $post )deve essere utilizzato per rendere disponibili i tag modello. WP_Queryutilizza il ciclo e i tag modello sono disponibili per impostazione predefinita

  • get_postspassa 'ignore_sticky_posts' => 1a WP_Query, quindi get_postsper impostazione predefinita ignora i post appiccicosi

Sulla base di quanto sopra, se utilizzare get_postso WP_Querydipende da te e cosa hai effettivamente bisogno dalla query. Quanto sopra dovrebbe guidarti nella tua scelta


1
Vorrei poter rispondere alle mie preferite. Questo spiega così tanto.
Patrik Alienus,

1
Grande spiegazione! "get_posts () dovrebbe essere usato solo per query non impaginate. La paginazione di get_posts è davvero un gran casino. WP_Query dovrebbe essere usato per tutte le query impaginate" È fondamentalmente tutto ciò che qualcuno ha bisogno di conoscere imo.
Bullyen,

32

La differenza di base è che in query_posts()realtà è solo per modificare il loop corrente. Una volta terminato, è necessario ripristinare il loop e inviarlo nel modo giusto. Questo metodo è anche un po 'più semplice da capire, semplicemente perché la tua "query" è fondamentalmente una stringa URL che passi alla funzione, in questo modo:

query_posts('meta_key=color&meta_value=blue'); 

D'altra parte, WP_Queryè più uno strumento generico, ed è più come scrivere direttamente query MySQL di quanto non query_posts()sia. Puoi anche usarlo ovunque (non solo nel Loop) e non interferisce con nessuna post query attualmente in esecuzione.

Tendo a usarlo WP_Querypiù spesso, come succede. Davvero, si ridurrà al tuo caso specifico.


15

Semplicemente non è necessario utilizzare query_posts(). Tutto ciò che fa è creare un'istanza di un nuovo oggetto WP_Query e riassegnare quel nuovo oggetto a global wp_query.

Per riferimento, la seguente è quella query_posts()funzione effettiva .

 function query_posts($query) {
        $GLOBALS['wp_query'] = new WP_Query();
        return $GLOBALS['wp_query']->query($query);
    }

Crea un'istanza del tuo oggetto WP_Query se desideri creare uno script di query personalizzato approfondito. Oppure usa get_posts()se tutto ciò che devi fare è qualche manipolazione leggera qua e là.

In entrambi i casi, consiglio vivamente di farti un favore e di andare a wp_includes/query.phpleggere la WP_Querylezione.


14

Assicurarsi di utilizzare wp_reset_query()dopo l'uso query_posts()perché influirà anche sul risultato di altre query.


10

Se ricordo bene la lettura, essenzialmente "il ciclo" sta facendo WP_Querynei file core, ma in un modo più facile da capire.


6
  • query_posts () : potrebbe essere utilizzato in un solo caso se è necessario modificare la query principale. Imposta molte variabili globali;
  • get_posts () : è molto simile in meccanica e accetta gli stessi argomenti, ma restituisce una serie di post
  • WP_Query : è possibile creare e lavorare con il proprio oggetto. Un po 'più complesso, meno restrizioni, è sicuro da usare ovunque.

-6

Direi di non usare get_posts()in un plugin. Essa impone filtri molto restrittive in alcuni casi (set di suppress_filters, ignore_sticky_postsecc) e dovrebbe probabilmente essere utilizzato solo in un tema quando si desidera qualcosa di fatto veloce.

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.