Kapan sebaiknya Anda menggunakan WP_Query vs query_posts () vs get_posts ()?

Jawaban:

667
  • query_posts()terlalu sederhana dan cara bermasalah untuk memodifikasi kueri utama halaman dengan menggantinya dengan instance baru dari kueri. Itu tidak efisien (menjalankan kembali query SQL) dan akan langsung gagal dalam beberapa keadaan (terutama sering ketika berhadapan dengan posting pagination). Kode WP modern apa pun harus menggunakan metode yang lebih andal, seperti memanfaatkan pre_get_postshook, untuk tujuan ini. TL; DR tidak pernah menggunakan query_posts () .

  • get_posts() sangat mirip dalam penggunaan dan menerima argumen yang sama (dengan beberapa nuansa, seperti standar yang berbeda), tetapi mengembalikan berbagai posting, tidak mengubah variabel global dan aman untuk digunakan di mana saja.

  • WP_Queryadalah kelas yang memberdayakan keduanya di belakang layar, tetapi Anda juga dapat membuat dan bekerja dengan instance Anda sendiri. Sedikit lebih rumit, batasan lebih sedikit, juga aman digunakan di mana saja.

Jarang
sumber
8
@jjeaton query_posts()adalah fungsi pembungkus kecil untuk WP_Query, satu-satunya hal tambahan yang dilakukannya (sesuai flowchart) adalah menimpa global$wp_query
Rarst
7
@jjeaton Mengganti query_posts()dengan tidak WP_Queryakan membuat perbedaan dalam kinerja, permintaan halaman asli masih akan berjalan karena itu adalah bagian dari beban inti. Kueri itu akan berjalan bahkan jika file template Anda tidak memiliki loop sama sekali.
Rarst
116
Tidak dapat menghilangkan perasaan bahwa ini adalah postingan yang paling jenius dan terunggul di WPSE. Harus di Codex juga.
kaiser
8
Saya hanya akan menambahkan deskripsi saya yang paling jelas tentang masalah "kinerja query_posts ()": Menggunakan query_posts () atau WP_Query dalam file templat akan memiliki biaya kinerja yang sama: permintaan yang baru saja Anda lakukan. Masalah yang dibahas dalam artikel kodeks adalah bahwa jika Anda benar-benar ingin mengganti kueri, Anda harus melakukannya dengan memfilter kueri_post asli () dengan filter 'parse_query'. Dengan cara itu Anda hanya memiliki satu, asli, permintaan yang diinginkan, daripada melakukan permintaan kedua untuk menggantinya dengan canggung. query_posts () TIDAK PERNAH CARA !! TIDAK PERNAH!
jerclarke
22
Ada penjelasan yang luar biasa dari query_posts yang ditulis oleh John James Jacoby di blog developer.wordpress.com yang membuat semua jawaban ini keluar dari air. Titik utama: query_poststidak memodifikasi loop utama sama sekali, itu menggantikan itu setelah itu sudah berjalan. Cara terbaik untuk memodifikasi loop utama adalah melalui pre_get_postsfilter. developer.wordpress.com/2012/05/14/…
Dan Gayle
65

query_posts- Anda seharusnya tidak pernah menggunakannya query_posts. Terlepas dari apa yang dikatakan @Rarst, masalah yang sangat besar query_postsadalah, ia merusak objek permintaan utama (disimpan di $wp_query). Banyak plugin dan kode khusus bergantung pada objek kueri utama, jadi dengan melanggar objek kueri utama berarti Anda melanggar fungsi plugins dan kode kustom. Hanya satu fungsi seperti itu yang merupakan fungsi pagination yang penting, jadi jika Anda memecah kueri utama, Anda memutuskan pagination.

Untuk membuktikan seberapa buruknya query_posts, pada templat apa pun, lakukan yang berikut dan bandingkan hasilnya

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

get_postsdan WP_Querymerupakan cara yang benar untuk membuat kueri sekunder ( seperti pos terkait, bilah geser, konten unggulan, dan konten pada halaman depan statis ) dengan. Perlu dicatat, Anda tidak boleh menggunakan salah satu dari dua yang mendukung permintaan utama di halaman rumah, halaman tunggal atau jenis halaman arsip apa pun karena akan merusak fungsionalitas halaman. Jika Anda perlu memodifikasi permintaan utama, gunakan pre_get_postsuntuk melakukannya, dan bukan permintaan khusus. ( PEMBARUAN: Untuk halaman depan statis dan halaman sebenarnya, lihat Menggunakan pre_get_post pada halaman benar dan halaman depan statis *)

Intinya, WP_Querydigunakan oleh kueri utama dan juga digunakan oleh get_posts, tetapi meskipun get_posts()menggunakan WP_Query, ada beberapa perbedaan

  • get_postslebih cepat dari WP_Query. Margin tergantung pada jumlah posting total situs. Alasan untuk ini adalah, get_postslewat 'no_found_rows' => truesecara default WP_Queryyang melompati / mematahkan pagination secara legal. Dengan 'no_found_rows' => true, WP_Querydapatkan jumlah posting yang ditanyakan, kemudian ditebus, di mana secara default, pencarian lebih lanjut untuk semua posting yang cocok dengan kueri untuk menghitung pagination.

    Untuk alasan ini, get_posts()harus digunakan hanya untuk permintaan non paginasi. Paginating get_postsbenar-benar satu kekacauan besar. WP_Queryharus digunakan untuk semua permintaan paginasi

  • get_posts()tidak dipengaruhi oleh posts_*filter yang WP_Querydipengaruhi oleh filter ini. Alasannya adalah bahwa get_posts, secara default, beralih 'suppress_filters' => truekeWP_Query

  • get_postsmemiliki beberapa parameter tambahan seperti include, exclude, numberpostsdan category. Parameter ini dapat diubah menjadi parameter yang valid untuk WP_Querysebelum diteruskan ke WP_Query. includediubah menjadi post__in, excludeke post__not_in, categoryke catdan numberpostske posts_per_page. Sebagai catatan, semua parameter yang dapat dilewati WP_Queryberfungsi dengan baik get_posts, Anda dapat mengabaikan dan tidak menggunakan parameter defaultget_posts

  • get_postsmengembalikan hanya $postsproperti WP_Querysementara WP_Querymengembalikan objek lengkap. Objek ini cukup berguna ketika datang ke conditional, pagination dan info berguna lainnya yang dapat digunakan di dalam loop.

  • get_poststidak menggunakan loop, tetapi foreachloop untuk menampilkan posting. Juga, tidak ada tag templat yang tersedia secara default. setup_postdata( $post )harus digunakan untuk membuat tag templat tersedia. WP_Querymenggunakan loop dan tag templat tersedia secara default

  • get_postsberalih 'ignore_sticky_posts' => 1ke WP_Query, jadi get_postssecara default mengabaikan posting yang lengket

Berdasarkan hal di atas, apakah akan menggunakan get_postsatau WP_Queryterserah Anda dan apa yang sebenarnya Anda butuhkan dari permintaan. Di atas akan memandu Anda dalam pilihan Anda

Pieter Goosen
sumber
1
Saya berharap saya dapat jawaban favorit. Ini menjelaskan banyak hal.
Patrik Alienus
1
Penjelasan Hebat! "get_posts () harus digunakan untuk permintaan non paginasi saja. Membuat pag_ get_posts benar-benar satu kekacauan besar. WP_Query harus digunakan untuk semua permintaan paginasi" "Pada dasarnya semua orang perlu tahu imo.
Bullyen
32

Perbedaan mendasarnya adalah query_posts()hanya benar-benar untuk memodifikasi Loop saat ini. Setelah Anda selesai, Anda perlu mengatur ulang loop dan mengirimkannya dengan selamat. Metode ini juga sedikit lebih mudah dimengerti, hanya karena "kueri" Anda pada dasarnya adalah string URL yang Anda berikan ke fungsi, seperti:

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

Di sisi lain, WP_Querylebih merupakan alat tujuan umum, dan lebih seperti menulis pertanyaan MySQL secara langsung query_posts(). Anda juga dapat menggunakannya di mana saja (tidak hanya di Loop) dan tidak mengganggu kueri pos yang sedang berjalan.

Saya cenderung menggunakan WP_Querylebih sering, karena itu terjadi. Sungguh, ini akan sampai pada kasus spesifik Anda.

nickmjones
sumber
15

Hanya tidak perlu digunakan query_posts(). Semua yang dilakukannya adalah instantiate objek WP_Query baru dan menugaskan kembali objek baru itu global wp_query.

Untuk referensi, berikut ini adalah query_posts()fungsi sebenarnya .

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

Instantiate objek WP_Query Anda sendiri jika Anda ingin membuat skrip kueri khusus yang mendalam. Atau gunakan get_posts()jika yang perlu Anda lakukan hanyalah manipulasi cahaya di sana-sini.

Dalam kedua kasus itu, saya sangat menyarankan untuk melakukan kebaikan bagi diri Anda sendiri dan pergi ke wp_includes/query.phpdan meneliti WP_Querykelas.

PemberontakPhoenix
sumber
14

Pastikan Anda menggunakan wp_reset_query()setelah menggunakan query_posts()karena akan mempengaruhi hasil kueri lainnya juga.

Bindiya Patoliya
sumber
10

Jika saya ingat pernah membaca dengan benar, pada dasarnya "loop" melakukan WP_Querydi file inti, tetapi dengan cara yang lebih mudah dimengerti.

tw2113
sumber
6
  • query_posts () : mungkin digunakan dalam satu-satunya kasus jika Anda perlu mengubah kueri utama. Ini menetapkan banyak variabel global;
  • get_posts () : sangat mirip dalam mekanika dan menerima argumen yang sama, tetapi mengembalikan array posting
  • WP_Query : Anda dapat membuat dan bekerja dengan objek sendiri. Sedikit lebih rumit, lebih sedikit pembatasan, aman digunakan di mana saja.
dalveer
sumber
-6

Saya akan mengatakan jangan gunakan get_posts()dalam plugin. Memaksakan filter yang sangat ketat dalam beberapa kasus (set ini suppress_filters, ignore_sticky_posts, dll) dan harus mungkin hanya digunakan dalam tema ketika Anda ingin sesuatu dilakukan cepat.

m4olivei
sumber