Pertanyaan penting
Menggali Mari ke trio: ::query_posts
, ::get_posts
dan class WP_Query
untuk memahami ::query_posts
lebih baik.
Landasan untuk mendapatkan data di WordPress adalah WP_Query
kelasnya. Baik metode ::query_posts
dan ::get_posts
gunakan kelas itu.
Perhatikan bahwa kelas tersebut WP_Query
juga berisi metode dengan nama yang sama: WP_Query::query_posts
dan WP_Query::get_posts
, tetapi kami sebenarnya hanya mempertimbangkan metode global, jadi jangan bingung.
Memahami WP_Query
Kelas yang dipanggil WP_Query
telah diperkenalkan kembali pada tahun 2004. Semua bidang memiliki tanda ☂ (payung) di mana ada pada tahun 2004. Kolom tambahan ditambahkan kemudian.
Berikut adalah WP_Query
strukturnya:
class WP_Query (as in WordPress v4.7)
public $query; ☂
public $query_vars = array(); ☂
public $tax_query;
public $meta_query = false;
public $date_query = false;
public $queried_object; ☂
public $queried_object_id; ☂
public $request;
public $posts; ☂
public $post_count = 0; ☂
public $current_post = -1; ☂
public $in_the_loop = false;
public $post; ☂
public $comments;
public $comment_count = 0;
public $current_comment = -1;
public $comment;
public $found_posts = 0;
public $max_num_pages = 0;
public $max_num_comment_pages = 0;
public $is_single = false; ☂
public $is_preview = false; ☂
public $is_page = false; ☂
public $is_archive = false; ☂
public $is_date = false; ☂
public $is_year = false; ☂
public $is_month = false; ☂
public $is_day = false; ☂
public $is_time = false; ☂
public $is_author = false; ☂
public $is_category = false; ☂
public $is_tag = false;
public $is_tax = false;
public $is_search = false; ☂
public $is_feed = false; ☂
public $is_comment_feed = false;
public $is_trackback = false; ☂
public $is_home = false; ☂
public $is_404 = false; ☂
public $is_embed = false;
public $is_paged = false;
public $is_admin = false; ☂
public $is_attachment = false;
public $is_singular = false;
public $is_robots = false;
public $is_posts_page = false;
public $is_post_type_archive = false;
private $query_vars_hash = false;
private $query_vars_changed = true;
public $thumbnails_cached = false;
private $stopwords;
private $compat_fields = array('query_vars_hash', 'query_vars_changed');
private $compat_methods = array('init_query_flags', 'parse_tax_query');
private function init_query_flags()
WP_Query
adalah pisau tentara Swiss.
Beberapa hal tentang WP_Query
:
- itu adalah sesuatu yang dapat Anda kendalikan melalui argumen yang Anda berikan
- itu serakah secara default
- itu memegang zat untuk perulangan
- disimpan di ruang global x2
- itu bisa primer atau sekunder
- ini menggunakan kelas pembantu
- ia memiliki
pre_get_posts
kait berguna
- bahkan memiliki dukungan untuk loop bersarang
- itu memegang string kueri SQL
- itu memegang jumlah hasil
- itu memegang hasil
- itu memegang daftar semua argumen permintaan yang mungkin
- itu memegang bendera templat
- ...
Saya tidak bisa menjelaskan semua ini, tetapi beberapa di antaranya rumit, jadi mari kita berikan tips singkat.
WP_Query
adalah sesuatu yang dapat Anda kendalikan melalui argumen yang Anda berikan
The list of the arguments
---
attachment
attachment_id
author
author__in
author__not_in
author_name
cache_results
cat
category__and
category__in
category__not_in
category_name
comments_per_page
day
embed
error
feed
fields
hour
ignore_sticky_posts
lazy_load_term_meta
m
menu_order
meta_key
meta_value
minute
monthnum
name
no_found_rows
nopaging
order
p
page_id
paged
pagename
post__in
post__not_in
post_name__in
post_parent
post_parent__in
post_parent__not_in
post_type
posts_per_page
preview
s
second
sentence
static
subpost
subpost_id
suppress_filters
tag
tag__and
tag__in
tag__not_in
tag_id
tag_slug__and
tag_slug__in
tb
title
update_post_meta_cache
update_post_term_cache
w
year
Daftar ini dari WordPress versi 4.7 pasti akan berubah di masa depan.
Ini akan menjadi contoh minimal membuat WP_Query
objek dari argumen:
// WP_Query arguments
$args = array ( /* arguments*/ );
// creating the WP_Query object
$query = new WP_Query( $args );
// print full list of arguments WP_Query can take
print ( $query->query_vars );
WP_Query
serakah
Dibuat atas gagasan, get all you can
pengembang WordPress memutuskan untuk mendapatkan semua data yang memungkinkan sejak awal karena ini baik untuk kinerja . Inilah sebabnya mengapa secara default ketika kueri mengambil 10 posting dari database, ia juga akan mendapatkan istilah dan metadata untuk posting ini melalui kueri terpisah. Persyaratan dan metadata akan di-cache (prefetched).
Perhatikan caching hanya untuk satu permintaan seumur hidup.
Anda dapat menonaktifkan caching jika Anda mengatur update_post_meta_cache
dan update_post_term_cache
untuk false
saat mengatur WP_Query
argumen. Ketika caching dinonaktifkan, data akan diminta dari database hanya berdasarkan permintaan.
Untuk sebagian besar caching blog WordPress berfungsi dengan baik, tetapi ada beberapa kesempatan ketika Anda menonaktifkan caching.
WP_Query
menggunakan kelas pembantu
Jika Anda memeriksa WP_Query
bidang di sana Anda memiliki tiga ini:
public $tax_query;
public $meta_query;
public $date_query;
Anda bisa membayangkan menambahkan baru di masa depan.
WP_Query
memegang zat untuk pengulangan
Dalam kode ini:
$query = new WP_Query( $args )
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
Anda mungkin memperhatikan WP_Query
memiliki substansi yang dapat Anda lakukan berulang kali. Metode pembantu ada di sana juga. Anda cukup mengatur while
loop.
Catatan. for
dan while
loop secara semantik setara.
WP_Query
primer dan sekunder
Di WordPress Anda memiliki satu kueri primer dan nol atau lebih kueri sekunder .
Dimungkinkan untuk tidak memiliki permintaan utama, tetapi ini berada di luar cakupan artikel ini.
Permintaan primer dikenal sebagai permintaan utama atau permintaan biasa . Permintaan sekunder juga disebut permintaan khusus .
WordPress menggunakan WP_Rewrite
kelas awal untuk membuat argumen kueri berdasarkan pada URL. Berdasarkan argumen ini, ia menyimpan dua objek identik di ruang global. Kedua hal ini akan menampung permintaan utama.
global $wp_query @since WordPress 1.5
global $wp_the_query @since WordPress 2.1
Ketika kami mengatakan permintaan utama kami memikirkan variabel-variabel ini. Pertanyaan lain dapat disebut sekunder atau kustom.
Ini sepenuhnya legal untuk menggunakan salah satu global $wp_query
atau $GLOBALS['wp_query']
, tetapi menggunakan notasi kedua jauh lebih penting, dan menyimpan mengetikkan garis tambahan di dalam lingkup fungsi.
$GLOBALS['wp_query']
dan $GLOBALS['wp_the_query']
merupakan objek yang terpisah. $GLOBALS['wp_the_query']
harus tetap beku.
WP_Query
memiliki pre_get_posts
kait berguna .
Ini adalah kait tindakan. Itu akan berlaku untuk contoh apa pun WP_Query
. Anda menyebutnya seperti:
add_action( 'pre_get_posts', function($query){
if ( is_category() && $query->is_main_query() ) {
// set your improved arguments
$query->set( ... );
...
}
return $query;
});
Pengait ini bagus dan dapat mengubah argumen kueri apa pun.
Inilah yang dapat Anda baca :
Kebakaran setelah objek variabel kueri dibuat, tetapi sebelum kueri aktual dijalankan.
Jadi kait ini adalah manajer argumen tetapi tidak dapat membuat WP_Query
objek baru . Jika Anda memiliki satu permintaan primer dan satu permintaan sekunder, pre_get_posts
tidak dapat membuat yang ketiga. Atau jika Anda hanya memiliki satu primer, itu tidak dapat membuat sekunder.
Catatan jika Anda perlu mengubah permintaan utama hanya Anda yang dapat menggunakan request
hook juga.
WP_Query
mendukung loop bersarang
Skenario ini dapat terjadi jika Anda menggunakan plugin, dan Anda memanggil fungsi plugin dari template.
Berikut ini contoh showcase WordPress yang memiliki fungsi pembantu bahkan untuk loop bersarang:
global $id;
while ( have_posts() ) : the_post();
// the custom $query
$query = new WP_Query( array( 'posts_per_page' => 5 ) );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) : $query->the_post();
echo '<li>Custom ' . $id . '. ' . get_the_title() . '</li>';
endwhile;
}
wp_reset_postdata();
echo '<li>Main Query ' . $id . '. ' . get_the_title() . '</li>';
endwhile;
Outputnya akan seperti ini sejak saya menginstal data uji unit tema :
Custom 100. Template: Sticky
Custom 1. Hello world!
Custom 10. Markup: HTML Tags and Formatting
Custom 11. Markup: Image Alignment
Custom 12. Markup: Text Alignment
Custom 13. Markup: Title With Special Characters
Main Query 1. Hello world!
Meskipun saya meminta 5 posting di custom $ query itu akan mengembalikan saya enam, karena posting lengket akan berjalan bersama. Jika tidak ada wp_reset_postdata
dalam contoh sebelumnya output akan seperti ini, karena $GLOBALS['post']
akan tidak valid.
Custom 1001. Template: Sticky
Custom 1. Hello world!
Custom 10. Markup: HTML Tags and Formatting
Custom 11. Markup: Image Alignment
Custom 12. Markup: Text Alignment
Custom 13. Markup: Title With Special Characters
Main Query 13. Markup: Title With Special Characters
WP_Query
memiliki wp_reset_query
fungsi
Ini seperti tombol reset. $GLOBALS['wp_the_query']
harus dibekukan sepanjang waktu, dan plugin atau tema tidak boleh mengubahnya.
Inilah yang wp_reset_query
dilakukan:
function wp_reset_query() {
$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
wp_reset_postdata();
}
Keterangan aktif get_posts
get_posts
seperti
File: /wp-includes/post.php
1661: function get_posts( $args = null ) {
1662: $defaults = array(
1663: 'numberposts' => 5,
1664: 'category' => 0, 'orderby' => 'date',
1665: 'order' => 'DESC', 'include' => array(),
1666: 'exclude' => array(), 'meta_key' => '',
1667: 'meta_value' =>'', 'post_type' => 'post',
1668: 'suppress_filters' => true
1669: );
... // do some argument parsing
1685: $r['ignore_sticky_posts'] = true;
1686: $r['no_found_rows'] = true;
1687:
1688: $get_posts = new WP_Query;
1689: return $get_posts->query($r);
Nomor baris dapat berubah di masa mendatang.
Itu hanya pembungkus di sekitar WP_Query
yang mengembalikan posting objek permintaan.
The ignore_sticky_posts
set untuk sarana benar tulisan lengket mungkin muncul hanya dalam posisi alami. Tidak akan ada posting yang lengket di depan. Set lainnya no_found_rows
ke true berarti API database WordPress tidak akan digunakan SQL_CALC_FOUND_ROWS
untuk mengimplementasikan pagination, mengurangi beban pada database untuk mengeksekusi baris yang ditemukan .
Ini berguna saat Anda tidak membutuhkan pagination. Kami mengerti sekarang kami dapat meniru fungsi ini dengan permintaan ini:
$args = array ( 'ignore_sticky_posts' => true, 'no_found_rows' => true);
$query = new WP_Query( $args );
print( $query->request );
Berikut adalah permintaan SQL yang sesuai:
SELECT wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 10
Bandingkan apa yang kita miliki sekarang dengan permintaan SQL sebelumnya di mana SQL_CALC_FOUND_ROWS
ada.
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 10
Permintaan tanpa SQL_CALC_FOUND_ROWS
akan lebih cepat.
Keterangan aktif query_posts
Kiat: Awalnya pada tahun 2004 hanya ada global $wp_query
. Pada versi WordPress 2.1 $wp_the_query
datang. Tip: $GLOBALS['wp_query']
dan $GLOBALS['wp_the_query']
merupakan objek yang terpisah.
query_posts()
adalah WP_Query
pembungkus. Ini mengembalikan referensi ke WP_Query
objek utama , dan pada saat yang sama akan mengatur global $wp_query
.
File: /wp-includes/query.php
function query_posts($args) {
$GLOBALS['wp_query'] = new WP_Query();
return $GLOBALS['wp_query']->query($args);
}
Dalam PHP4 semuanya, termasuk objek, diteruskan oleh nilai. query_posts
seperti ini:
File: /wp-includes/query.php (WordPress 3.1)
function &query_posts($args) {
unset($GLOBALS['wp_query']);
$GLOBALS['wp_query'] =& new WP_Query();
return $GLOBALS['wp_query']->query($args);
}
Harap perhatikan dalam skenario umum dengan satu kueri primer dan satu kueri sekunder, kami memiliki tiga variabel berikut:
$GLOBALS['wp_the_query']
$GLOBALS['wp_query'] // should be the copy of first one
$custom_query // secondary
Katakanlah masing-masing dari ketiganya membutuhkan 1M memori. Total akan menjadi 3 M memori. Jika kita gunakan query_posts
, $GLOBALS['wp_query']
akan tidak disetel dan dibuat lagi.
PHP5 + harus pintar mengosongkan $GLOBALS['wp_query']
objek, sama seperti di PHP4 kita melakukannya denganunset($GLOBALS['wp_query']);
function query_posts($args) {
$GLOBALS['wp_query'] = new WP_Query();
return $GLOBALS['wp_query']->query($args);
}
Akibatnya query_posts
menghabiskan 2M memori secara total, sementara get_posts
mengkonsumsi 3 M memori.
Catatan dalam query_posts
kita tidak mengembalikan objek yang sebenarnya, tetapi referensi ke objek.
Dari php.net : Referensi PHP adalah alias, yang memungkinkan dua variabel berbeda untuk menulis ke nilai yang sama. Pada PHP 5, variabel objek tidak mengandung objek itu sendiri sebagai nilai lagi. Ini hanya berisi pengenal objek yang memungkinkan pengakses objek untuk menemukan objek yang sebenarnya. Ketika suatu objek dikirim dengan argumen, dikembalikan atau ditugaskan ke variabel lain, variabel yang berbeda bukan alias: mereka memegang salinan pengidentifikasi, yang menunjuk ke objek yang sama.
Juga di PHP5 + operator assign (=) pintar. Ini akan menggunakan salinan dangkal dan bukan salinan objek keras. Ketika kita menulis seperti ini $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
hanya data yang akan disalin, bukan seluruh objek karena ini berbagi jenis objek yang sama.
Ini salah satu contohnya
print( md5(serialize($GLOBALS['wp_the_query']) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
query_posts( '' );
print( md5(serialize($GLOBALS['wp_the_query']) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
Akan menghasilkan:
f14153cab65abf1ea23224a1068563ef
f14153cab65abf1ea23224a1068563ef
f14153cab65abf1ea23224a1068563ef
d6db1c6bfddac328442e91b6059210b5
Coba setel ulang kueri:
print( md5(serialize($GLOBALS['wp_the_query'] ) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
query_posts( '' );
wp_reset_query();
print( md5(serialize($GLOBALS['wp_the_query'] ) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
Akan menghasilkan:
f14153cab65abf1ea23224a1068563ef
f14153cab65abf1ea23224a1068563ef
f14153cab65abf1ea23224a1068563ef
f14153cab65abf1ea23224a1068563ef
Anda dapat membuat masalah meskipun Anda menggunakannya WP_Query
print( md5(serialize($GLOBALS['wp_the_query'] ) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
global $wp_query;
$wp_query = new WP_Query( array( 'post_type' => 'post' ) );
print( md5(serialize($GLOBALS['wp_the_query'] ) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
Tentu saja, solusinya adalah menggunakan wp_reset_query
fungsi lagi.
print( md5(serialize($GLOBALS['wp_the_query'] ) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
global $wp_query;
$wp_query = new WP_Query( array( 'post_type' => 'post' ) );
wp_reset_query();
print( md5(serialize($GLOBALS['wp_the_query'] ) ) );
print( md5(serialize($GLOBALS['wp_query'] ) ) );
Inilah sebabnya saya pikir query_posts
mungkin lebih baik dari sudut pandang memori. Tetapi Anda harus selalu melakukan wp_reset_query
trik.